Docs
Grid

Grid

Grid is the design system's CSS Grid based container. It creates two-dimensional layouts with named areas, responsive breakpoints and gaps declared in theme tokens.

The layout configuration lives in the medias prop — an object where each key is a breakpoint (xs, sm, md, ...) with columns, rows, areas and gap/columnGap/rowGap. The xs breakpoint is treated as mobile-first.

When to use

✅ Use when…🚫 Avoid when…
  • For two-dimensional layouts (rows and columns) where the position of the children matters.
  • When you need named areas (grid-template-areas) — put area="header" on the children and their position follows the layout.
  • For layouts that change shape across breakpoints — just declare medias for each one.
  • For linear stacks (a simple row or column). Use Flex with gap.
  • For regular grids without named areas that fit in a few lines of CSS — Flex with flex-wrap is usually lighter.

Basic example — areas that rearrange per breakpoint

Resize the window to see the areas swapping positions.

A
B
C
import { Flex } from '@apollion-dsi/core/containers/flex';
import { Grid, GridBreakpoints } from '@apollion-dsi/core/containers/grid';
import { Text } from '@apollion-dsi/core/elements/text';
 
const medias: GridBreakpoints = {
  xs: { columns: '33%',  rows: '100px', areas: `"a b c"` },
  sm: { columns: '50px', rows: '100px', areas: `"c b a"` },
  md: { columns: '500px', rows: '100px', areas: `"b c a"` },
};
 
<Grid medias={medias}>
  <Paper bgColor="main" area="a" justifyContent="center" alignItems="center" deep={0}>
    <Text contrast="main">A</Text>
  </Paper>
  <Paper bgColor="neutral.100" area="b" justifyContent="center" alignItems="center" deep={0}>
    <Text contrast="main">B</Text>
  </Paper>
  <Paper bgColor="grayscale.20" area="c" justifyContent="center" alignItems="center" deep={0}>
    <Text contrast="main">C</Text>
  </Paper>
</Grid>

Layout example — header / content / sidebar

HEADER
CONTENT
SIDEBAR
const medias: GridBreakpoints = {
  xs: {
    columns: '100px',
    areas: `
      "Head Head"
      "Content Sidebar"
    `,
    rows: '1fr 100px',
  },
  md: {
    columns: '100px',
    areas: `
      "Head Head"
      "Sidebar Content"
    `,
    rows: '1fr 100px',
  },
};
 
<Grid medias={medias}>
  <Paper area="Head" bgColor="main" deep={0}><Text contrast="main">HEADER</Text></Paper>
  <Paper area="Content" bgColor="neutral.100" deep={0}><Text>CONTENT</Text></Paper>
  <Paper area="Sidebar" bgColor="grayscale.20" deep={0}><Text>SIDEBAR</Text></Paper>
</Grid>

Auto-fit card grids — zero media queries

The typed auto-repeat template wraps tracks by the space available in the container — the card grid needs no breakpoints at all:

<Grid medias={{ xs: { columns: { autoFit: '250px' }, gap: 'medium' } }}>
  <Card title={{ text: 'A' }} />
  <Card title={{ text: 'B' }} />
  <Card title={{ text: 'C' }} />
</Grid>

autoFit stretches cards to fill the row; autoFill keeps empty slots. The emitted template guards the minimum with min(<min>, 100%), so a track never forces horizontal overflow on a viewport narrower than the minimum — mobile-safe by construction.

Centering without a nested Flex

Alignment belongs to the grid. Center every cell's content from the host (or per breakpoint inside medias) — no Flex wrapper just to center.

centered
centered
<Grid height="100%" alignItems="center" justifyItems="center" medias={{ columns: '1fr 1fr' }}>
  <Paper>centered</Paper>
</Grid>

API summary

PropTypeDefaultDescription
mediasGridBreakpointsLayout per breakpoint (xs, sm, md, ...). Each key accepts columns, rows, areas, gap, columnGap, rowGap and the alignment keys below. columns also takes { autoFit: '<min>' } / { autoFill: '<min>', max? } for container-driven wrapping.
alignItems / justifyItems / placeItems / justifyContent / alignContentstart · end · center · stretch (+ between / around / evenly on the content axes)Box alignment of the cells — on the host or per breakpoint inside medias.
bgColor / colorBgColorsTypesBackground / text color via theme.
borderStyle / borderWidth / borderColor / borderRadiusstringBorders via theme.
height / maxHeight / minHeightnumber | stringVertical dimensions.
width / maxWidth / minWidthnumber | stringHorizontal dimensions.
p / px / py / pt / pb / pl / prnumber | SpacingInterfacePadding (shorthands).
m / mx / my / mt / mb / ml / mrnumber | SpacingInterfaceMargin (shorthands).
viewportMedias / cqPartial<Record<'xs' | 'sm' | 'md' | 'lg' | 'xl', …>>Object-per-breakpoint responsive channels (viewport / container) for arbitrary factory props — the non-grid-template surface (see Flex).
as / forwardedAsReact.ElementTypeRender as another element. Type a layout object as GridProps to set it without a local augmentation.

This component's API is the system's layout props (spacing, color, flex/grid, size, border).

GridPropsInterface carries the full factory surface (flex/alignSelf, the responsive prefixes, cq, viewportMedias, motion) — the same set the styled Grid accepts at runtime. Annotate a plain layout object as GridProps when it also needs the polymorphic as/forwardedAs.

Only declare areas in the breakpoints where the layout actually changes — if a breakpoint would repeat the same areas as xs, skip it there. Set columns/rows/areas only through the medias prop, not by overriding via styled-components. Every child positioned by areas needs its own area="…" prop, or it won't be placed.

See also

  • Linear container: Flex.
  • Base primitive: Base.