Grid

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 query
  • Grid.supportsGap is equivalent to the @supports (gap: 1px) CSS query

Try it out

Try looking at this example at several different window/screen sizes.

Basic usage: Pseudo-flex Mode

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>

Basic Usage: CSS 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).

Row & Column Integer Shortcut

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)">

Grid Areas

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'] }}>

Flex Compatibility

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.

IE Support

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.
  • The 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.
  • The repeat keyword is not supported.
  • All row/column start lines must be explicitly defined, since IE doesn’t support auto-flow.
  • The span keyword cannot be used in start lines.
  • All grid lines must be positive integers; IE doesn’t support negative or named grid lines.
  • IE doesn’t directly support grid-area, grid-row, or grid-column, and though we have a polyfill for those props, it doesn’t provide perfect support.
  • When defining grid end lines, either in 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.
  • These props are not supported at all: 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']} />

Properties

Grid

Supports all Box and Flex props, in addition to these:

rowsminus certain keywords like `repeat()`grid-template-rowscolumnscolsminus certain keywords like `repeat()`grid-template-columnsjustifyItemsjustifystart, end, center, stretchjustify-itemsalignItemsstart, end, center, stretchalign-itemsjustifyContentNonejustify-contentalignContentNonealign-contentautoFlowNonegrid-auto-flowautoRowsNonegrid-auto-rowsautoColumnsautoColsNonegrid-auto-columnsgridNonegridgridTemplateNonegrid-templategridTemplateAreasNonegrid-template-areasgridAreaspositive integer grid lines only
{ [className: string]: grid-area }

Grid Item

Supports all Flex.Item props, in addition to these:

Pseudo-flex Mode

tiny, small, medium, large, extraLarge1integer 1-12

CSS Grid

rowpositive integers onlygrid-rowrowStartpositive integers onlygrid-row-startrowEndpositive integers only; prefer `span`grid-row-endcolumncolpositive integers onlygrid-columncolumnStartcolStartpositive integers onlygrid-column-startcolumnEndcolEndpositive integers only; prefer `span`grid-column-endgridAreapositive integers onlygrid-areajustifySelfstart, end, center, stretchjustify-selfalignSelfstart, end, center, stretchalign-self