The Grid component has two main usagge modes:
Pseudo-flex mode: the default usage divides the element into 12 equal columns, and then allows you to define how many columns each child takes up at different screen sizes. For example, this item takes up 6 columns (half the element’s width) on tiny & small screens, 3 columns (one fourth) on medium screens, and 2 columns (one sixth) on larger screens:
<Grid>
<Grid.Item tiny={6} medium={3} large={2}>
</Grid>
CSS grid mode: you define how many rows & columns there are, how big they are, and where each child fits in the grid. The grid and child placement are controlled by styled-system props, so they can also be changed based on screen size. This grid will have one column on tiny screens, and two columns otherwise:
<Grid rows={[2, 1]} columns={[1, 2]}>
<Grid.Item gridArea="1/1" />
<Grid.Item gridArea={['2/1', '1/2]} />
</Grid>
Grid also has a couple of static booleans attached:
Grid.supportsGrid
is equivalent to the @supports (display: grid)
CSS queryGrid.supportsGap
is equivalent to the @supports (gap: 1px)
CSS queryTry looking at this example at several different window/screen sizes.
Conceptually this mode is similar to a flex wrap container with 12 discrete values for flex-basis;
it is actually implemented using CSS grid, however, because of the convenience of the fr
length unit:
fr
more accurately accounts for the CSS gap
property or margins than a percentage-based flex will do.
There isn’t much more to say usage-wise than what the initial example showed:
prop names are screen size breakpoints, values are the number of columns out of
12 that the item spans at that screen size. If a column span for a certain
breakpoint isn’t defined, Grid
will always use the next lowest size that is defined.
For example, if only tiny
and large
are defined, the tiny
value will be
applied to tiny, small, and medium screens, while the large
value will apply
to both large and extraLarge.
<Grid>
// Takes up half the width on tiny, small and medium, one fourth on large & extraLarge.
<Grid.Item tiny={6} large={3} />
</Grid>
This is normal CSS Grid implemented using styled-system. Some of the props have been renamed for convenience & to reduce boilerplate (see props table below).
For some of the most common use cases you can take a shortcut by simply passing the number of rows and/or columns you want, and Grid will pick a default “length”:
<Grid rows={3} cols={4}>
// Is equivalent to
<Grid rows="repeat(3, min-content)" cols="repeat(4, 1fr)">
While Grid fully supports the grid
, gridTemplate
, and gridTemplateAreas
props,
their syntax isn’t very React-friendly. An alternative/workaround is the gridAreas
prop,
which defines CSS classes that can be used to place grid items:
<Grid
rows={2}
cols="1fr 4fr min-content"
gridAreas={{
'left-column': '1 / 1',
'main-area': '1 / 2',
'right-column': '1 / 3',
'footer': '2 / 1 / span 1 / span 3',
}}
>
<Grid.Item className="left-column" />
<MainPanel className="main-area" />
<Box className="footer" />
</Grid>
Each class has a grid-area property
that defines the area. While not as flexible as grid templates, the named classes
can be applied to any element, not just Grid.Item
. These areas can also be defined
to be responsive: in this example, the defined area will be row 3 column 1 on tiny screens,
and row 2 column 2 on larger screens.
<Grid gridAreas={{ 'my-area': ['3 / 1', '2 / 2'] }}>
Grid also supports all the props from the Flex component, which can simplify the transition between a single column on mobile and multiple columns on larger screens. Here’s the responsive example from the beginning, rewritten using flex:
<Grid display={['flex', 'grid']} flexFlow="column" rows={1} cols={2}>
<Grid.Item gridArea="1/1" />
<Grid.Item gridArea="1/2" />
</Grid>
That might not seem much simpler at a glance, but the more child items you have, the more you save by not having to place them all twice.
Contrary to popular belief, IE 11 does have pretty good grid support. It’s based on an old version of the grid specification, though, so it can’t be considered “full” support; if you need to keep your site IE-compatible, keep these points in mind:
Grid.supportsGrid
is false on IE, due to only partial support.display
property is -ms-grid
; this is set by default, but you need to know it if you change the display, e.g. for the flex column trick mentioned above.repeat
keyword is not supported.span
keyword cannot be used in start lines.grid-area
, grid-row
, or grid-column
, and though we have a polyfill for those props, it doesn’t provide perfect support.rowEnd
/colEnd
or in the polyfilled props, it works best to use span
.justifyItems
/justifySelf
& alignItems
/alignSelf
are supported, but only start
, center
, stretch
, and end
keywords.justifyContent
, alignContent
, autoFlow
, autoRows
, autoColumns
, grid
, gridTemplate
, and gridTemplateAreas
.// ✕ Incompatible
<Grid rows="repeat(2, min-content)" />
// ✓ Better
<Grid rows="min-content min-content" />
// ✕ Incompatible
<Grid.Item row="span 2 / -1" />
// ✓ Better
<Grid.Item row="3 / span 2" />
// ✕ Incompatible
<Grid.Item row="auto" col="custom-area" />
// ✓ Better
<Grid.Item row="3" col="5" />
// ✕ Incompatible: the polyfill doesn't have enough context to pair 6 & 4, 3 & 2, because of how styled-system processes responsive styles
<Grid.Item rowStart={[4, 2]} rowEnd={[6, 3]} />
// ✓ Better
<Grid.Item rowStart={[4, 2]} rowEnd={['span 2', 'span 1']} />
// ✓ Okay; here it works because there's no ambiguity in pairing start with end
<Grid.Item rowStart="4" rowEnd="6" col={['2/4', '4/8']} />
Supports all Box and Flex props, in addition to these:
rows
columns
cols
justifyItems
justify
alignItems
justifyContent
alignContent
autoFlow
autoRows
autoColumns
autoCols
grid
gridTemplate
gridTemplateAreas
gridAreas
{ [className: string]: grid-area }
Supports all Flex.Item props, in addition to these:
tiny, small, medium, large, extraLarge
row
rowStart
rowEnd
column
col
columnStart
colStart
columnEnd
colEnd
gridArea
justifySelf
alignSelf