Grid

Extends View. Renders as a <div> with display: grid.

All View props are inherited - including gap, rowGap and columnGap. Grid adds the full set of CSS Grid layout props via styled-system.

Examples

Default

A
B
C
D
const args: Partial<GridProps> = { gridTemplateColumns: '1fr 1fr', gap: 2 }

<Grid {...args}>
  <Cell label="A" />
  <Cell label="B" />
  <Cell label="C" />
  <Cell label="D" />
</Grid>

Placement Example

One
Two
Three
Four
Five
Six
<Grid
  gridTemplateColumns="repeat(3, 1fr)"
  gap={1}
  gridAutoRows="minmax(100px, auto)"
  maxWidth="940px"
>
  <Grid
    gridColumn="1 / 3"
    gridRow="1"
    bg="backdrop"
    borderColor="primary"
    borderWidth="thin"
    borderStyle="solid"
    borderRadius="sm"
    p={2}
  >
    One
  </Grid>
  <Grid
    gridColumn="2 / 4"
    gridRow="1 / 3"
    bg="backdrop"
    borderColor="primary"
    borderWidth="thin"
    borderStyle="solid"
    borderRadius="sm"
    p={2}
  >
    Two
  </Grid>
  <Grid
    gridColumn="1"
    gridRow="2 / 5"
    bg="backdrop"
    borderColor="primary"
    borderWidth="thin"
    borderStyle="solid"
    borderRadius="sm"
    p={2}
  >
    Three
  </Grid>
  <Grid
    gridColumn="3"
    gridRow="3"
    bg="backdrop"
    borderColor="primary"
    borderWidth="thin"
    borderStyle="solid"
    borderRadius="sm"
    p={2}
  >
    Four
  </Grid>
  <Grid
    gridColumn="2"
    gridRow="4"
    bg="backdrop"
    borderColor="primary"
    borderWidth="thin"
    borderStyle="solid"
    borderRadius="sm"
    p={2}
  >
    Five
  </Grid>
  <Grid
    gridColumn="3"
    gridRow="4"
    bg="backdrop"
    borderColor="primary"
    borderWidth="thin"
    borderStyle="solid"
    borderRadius="sm"
    p={2}
  >
    Six
  </Grid>
</Grid>

Column Row Gap

1
2
3
4
5
6
const args: Partial<GridProps> = { gridTemplateColumns: 'repeat(3, 1fr)', columnGap: 4, rowGap: 1 }

<Grid {...args}>
  {Array.from({ length: 6 }, (_, i) => (
    <Cell key={i} label={String(i + 1)} />
  ))}
</Grid>

Three Columns

1
2
3
4
5
6
<Grid gridTemplateColumns="repeat(3, 1fr)" gap={3} p={2}>
  {Array.from({ length: 6 }, (_, i) => (
    <Cell key={i} label={String(i + 1)} />
  ))}
</Grid>

Auto Fill

1
2
3
4
5
6
7
8
<Grid gridTemplateColumns="repeat(auto-fill, minmax(120px, 1fr))" gap={2} p={2}>
  {Array.from({ length: 8 }, (_, i) => (
    <Cell key={i} label={String(i + 1)} />
  ))}
</Grid>

Named Areas

header
sidebar
content
footer
<Grid
  gridTemplateAreas='"header header" "sidebar content" "footer footer"'
  gridTemplateColumns="180px 1fr"
  gridTemplateRows="auto 1fr auto"
  gap={2}
  p={2}
  height="300px"
>
  <View bg="primary" p={2} borderRadius="sm" style={{ gridArea: 'header' }}>
    header
  </View>
  <View bg="secondary" p={2} borderRadius="sm" style={{ gridArea: 'sidebar' }}>
    sidebar
  </View>
  <View bg="secondary" p={2} borderRadius="sm" style={{ gridArea: 'content' }}>
    content
  </View>
  <View bg="primary" p={2} borderRadius="sm" style={{ gridArea: 'footer' }}>
    footer
  </View>
</Grid>

Gap Scale

gap={0}
A
B
C
gap={0.5}
A
B
C
gap={1}
A
B
C
gap={2}
A
B
C
gap={3}
A
B
C
gap={4}
A
B
C
<Grid gridTemplateColumns="1fr" gap={0}>
  {([0, 0.5, 1, 2, 3, 4] as const).map((g) => (
    <View key={g} mb={3}>
      <Typography variant="caption" as="div" color="secondary" mb={0.5}>
        gap={`{${g}}`}
      </Typography>
      <Grid gridTemplateColumns="1fr 1fr 1fr" gap={g}>
        <Cell label="A" />
        <Cell label="B" />
        <Cell label="C" />
      </Grid>
    </View>
  ))}
</Grid>

Auto Rows

Without gridAutoRows - row height follows content
short
tall content that grows the row
short
short
gridAutoRows="80px" - all rows fixed height
1
2
3
4
5
6
7
8
<Grid gridTemplateColumns="1fr" gap={0}>
  <Typography variant="caption" as="div" color="secondary" mb={1}>
    Without gridAutoRows - row height follows content
  </Typography>
  <Grid gridTemplateColumns="repeat(4, 1fr)" gap={2} mb={4}>
    <Cell label="short" />
    <View bg="secondary" borderRadius="sm" p={2}>
      tall content that grows the row
    </View>
    <Cell label="short" />
    <Cell label="short" />
  </Grid>

  <Typography variant="caption" as="div" color="secondary" mb={1}>
    gridAutoRows="80px" - all rows fixed height
  </Typography>
  <Grid gridTemplateColumns="repeat(4, 1fr)" gridAutoRows="80px" gap={2}>
    <Cell label="1" />
    <Cell label="2" />
    <Cell label="3" />
    <Cell label="4" />
    <Cell label="5" />
    <Cell label="6" />
    <Cell label="7" />
    <Cell label="8" />
  </Grid>
</Grid>

Auto Flow

gridAutoFlow="row" (default) - items fill row by row
A
B
C
D
E
F
gridAutoFlow="column" - items fill column by column
A
B
C
D
E
F
<Grid gridTemplateColumns="1fr" gap={0}>
  <Typography variant="caption" as="div" color="secondary" mb={1}>
    gridAutoFlow="row" (default) - items fill row by row
  </Typography>
  <Grid gridTemplateColumns="repeat(3, 1fr)" gridAutoFlow="row" gap={2} mb={4}>
    {['A', 'B', 'C', 'D', 'E', 'F'].map((l) => (
      <Cell key={l} label={l} />
    ))}
  </Grid>

  <Typography variant="caption" as="div" color="secondary" mb={1}>
    gridAutoFlow="column" - items fill column by column
  </Typography>
  <Grid gridTemplateRows="repeat(2, 60px)" gridAutoFlow="column" gap={2}>
    {['A', 'B', 'C', 'D', 'E', 'F'].map((l) => (
      <Cell key={l} label={l} />
    ))}
  </Grid>
</Grid>

Spanning Items

gridColumn="1 / -1" - full width
1
2
3
gridColumn="1 / 3" - spans 2
5
6
gridRow="3/5"
7
<Grid gridTemplateColumns="repeat(3, 1fr)" gap={2}>
  <Grid gridColumn="1 / -1" bg="primary" p={2} borderRadius="sm" justifyContent="center">
    gridColumn="1 / -1" - full width
  </Grid>
  <Cell label="1" />
  <Cell label="2" />
  <Cell label="3" />
  <Grid gridColumn="1 / 3" bg="secondary" p={2} borderRadius="sm" justifyContent="center">
    gridColumn="1 / 3" - spans 2
  </Grid>
  <Cell label="5" />
  <Cell label="6" />
  <Grid
    gridRow="3 / 5"
    gridColumn="3"
    bg="primary"
    p={2}
    borderRadius="sm"
    justifyContent="center"
  >
    gridRow="3/5"
  </Grid>
  <Cell label="7" />
</Grid>

Asymmetric Gap

columnGap={4} (32px) · rowGap={1} (8px)
1
2
3
4
5
6
columnGap={1} · rowGap={4}
1
2
3
4
5
6
<Grid gridTemplateColumns="1fr" gap={0}>
  <Typography variant="caption" as="div" color="secondary" mb={1}>
    columnGap={'{4}'} (32px) · rowGap={'{1}'} (8px)
  </Typography>
  <Grid gridTemplateColumns="repeat(3, 1fr)" columnGap={4} rowGap={1} mb={4}>
    {Array.from({ length: 6 }, (_, i) => (
      <Cell key={i} label={String(i + 1)} />
    ))}
  </Grid>

  <Typography variant="caption" as="div" color="secondary" mb={1}>
    columnGap={'{1}'} · rowGap={'{4}'}
  </Typography>
  <Grid gridTemplateColumns="repeat(3, 1fr)" columnGap={1} rowGap={4}>
    {Array.from({ length: 6 }, (_, i) => (
      <Cell key={i} label={String(i + 1)} />
    ))}
  </Grid>
</Grid>

Grid Area Prop

gridArea="header"
gridArea="sidebar"
gridArea="main"
gridArea="footer"
<Grid
  gridTemplateAreas='"header header header" "sidebar main main" "footer footer footer"'
  gridTemplateColumns="140px 1fr 1fr"
  gridTemplateRows="48px 1fr 40px"
  gap={2}
  p={2}
  height="280px"
>
  <Grid gridArea="header" bg="primary" p={2} borderRadius="sm" alignItems="center">
    gridArea="header"
  </Grid>
  <Grid gridArea="sidebar" bg="secondary" p={2} borderRadius="sm" alignItems="center">
    gridArea="sidebar"
  </Grid>
  <Grid gridArea="main" bg="secondary" p={2} borderRadius="sm" alignItems="center">
    gridArea="main"
  </Grid>
  <Grid gridArea="footer" bg="primary" p={2} borderRadius="sm" alignItems="center">
    gridArea="footer"
  </Grid>
</Grid>

Grid API reference