This post is about how to create a flexbox-based grid component in React. The component should be reusable, easy to configure, and allow us to make the following layouts:
----
----
----
----
------
------
------
----------
----------
----
----------------
----
-----------
----
Base React Componets
Let's create the components that we will work with.
const Grid = ({ children }) => (
<div className='grid'>
{children}
</div>
);
const GridRow = ({ children }) => (
<div className='grid__row'>
{children}
</div>
);
const GridColumn = ({ children }) => (
<div className='grid__column'>
{children}
</div>
);
Now I append GridRow
and GridColumn
to the Grid
component as static variables Grid.Row
and Grid.Column
.
import React from 'react';
import GridRow from './GridRow';
import GridColumn from './GridColumn';
const Grid = ({ children }) => (
<div className='grid'>
{children}
</div>
);
Grid.Row = GridRow;
Grid.Column = GridColumn;
export default Grid;
Base styles
As already mentioned, the grid is based on flexbox, so we need to set the display
property as 'flex'.
.grid, .grid__row {
display: flex;
width: 100%;
}
.grid {
flex-direction: column;
flex-wrap: nowrap;
}
.grid__row {
flex-direction: row;
flex-wrap: wrap;
}
Columns
In order to make a row with n-columns we need to set the width
property of the columns. For example, if we want to get a 4-columns row, the value of the column width should be 25%, of 3 columns - 33%, of 2 columns - 50%. Therefore, we need CSS classes for these cases.
.grid__row--columns-4 > [class^="grid__column"] {
width: 25%;
}
.grid__row--columns-3 > [class^="grid__column"] {
width: 33%;
}
.grid__row--columns-2 > [class^="grid__column"] {
width: 50%;
}
And let's modify the GridRow component.
import cx from 'classnames';
const GridRow = ({ children, columns = 4 }) => {
const cls = cx('grid__row', {
[`grid__row--columns-${columns}`]: columns,
});
return (
<div className={cls}>
{children}
</div>
);
};
And now we can do...
<Grid>
<Grid.Row columns={4}>
<Grid.Column>1</Grid.Column>
<Grid.Column>2</Grid.Column>
<Grid.Column>3</Grid.Column>
<Grid.Column>4</Grid.Column>
</Grid.Row>
</Grid>
----
----
----
----
<Grid>
<Grid.Row columns={3}>
<Grid.Column>1</Grid.Column>
<Grid.Column>2</Grid.Column>
<Grid.Column>3</Grid.Column>
</Grid.Row>
</Grid>
----
----
----
<Grid>
<Grid.Row columns={2}>
<Grid.Column>1</Grid.Column>
<Grid.Column>2</Grid.Column>
</Grid.Row>
</Grid>
----
----
Columns with different widths
In order to make columns with different widths, we use the 'flex-grow' property.
.grid__column--width-3 {
flex-grow: 3;
}
.grid__column--width-2 {
flex-grow: 2;
}
const GridColumn = ({ children, width }) => {
const cls = cx('grid__column', {
[`grid__column--width-${width}`]: width,
});
...
And now we can do such things:
<Grid>
<Grid.Row columns={4}>
<Grid.Column>1</Grid.Column>
<Grid.Column width={2}>2</Grid.Column>
<Grid.Column>3</Grid.Column>
</Grid.Row>
</Grid>
----
-----------
----
<Grid>
<Grid.Row columns={3}>
<Grid.Column>1</Grid.Column>
<Grid.Column width={2}>2</Grid.Column>
</Grid.Row>
</Grid>
----
----------------
Top comments (0)