Grid
Navigation & layoutBrick 0.1.12

Grid

Grid is Brick's two-dimensional layout primitive. `Grid.Root` creates exact equal columns or intrinsic responsive columns. Optional `Grid.Item` adds deliberate spans, line placement, and self-alignment; ordinary children remain valid grid items without wrappers.

Live example

Built from the published package

Interactive
Account
Billing
Security
Choose with confidence

Know when Grid is the right part

Use it when

Use Grid for peer-card collections, specimen matrices, comparison regions, settings summaries, exact equal tracks, intrinsic responsive collections, and asymmetric regions that need explicit item placement.

Choose another path when

Use Stack, HStack, or VStack for one-dimensional flow; Container for page width and gutters; Surface or Card for paint; and Atom DataGrid for interactive grid semantics and keyboard navigation. Grid is not a page-template language, breakpoint system, generic Box, or ARIA grid widget.

Installation and imports

tsx
import { Grid } from "@flowstack-ui/brick";
// or
import { Grid } from "@flowstack-ui/brick/grid";

import "@flowstack-ui/brick/styles.css";

The complete stylesheet above is the recommended default. For a measured route-aware build, replace it with the shared foundation and this component's stylesheet:

tsx
import "@flowstack-ui/brick/styles/core.css"; // once at the application root
import "@flowstack-ui/brick/styles/grid.css";

Add the modular stylesheet for every other Brick component the route renders. Do not combine modular styles with styles.css or tokens.css.

Public exports are Grid, GridRootProps, GridItemProps, GridRootElement, GridItemElement, GridColumns, GridLine, GridSpan, GridColumnSpan, GridGap, SpacingValue, GridMinItemSize, GridAlign, GridJustify, GridSelfAlign, GridSelfJustify, and ResponsiveValue.

Quick start

tsx
<Grid.Root minItemSize="md" gap="4">
  <Card.Root>Account</Card.Root>
  <Card.Root>Billing</Card.Root>
  <Card.Root>Security</Card.Root>
</Grid.Root>

Add Item only when placement is needed:

tsx
<Grid.Root columns={3} gap="4">
  <Card.Root>First</Card.Root>
  <Grid.Item columnSpan={2}>
    <Card.Root>Featured</Card.Root>
  </Grid.Item>
</Grid.Root>

Visual recipes and states

Explicit mode uses repeat(n, minmax(0, 1fr)). Intrinsic mode uses auto-fit with minimum sizes 8rem, 12rem, 16rem, 20rem, and 24rem for xs through xl. Legacy string gaps map to --brick-space-0 through --brick-space-6; numeric factors calculate from --brick-space-1; explicit CSS values pass through. See Layout spacing values.

Numeric Item column placement is for explicit-column Roots. Intrinsic Roots use native auto-placement or columnSpan="full" because numeric placement can create unintended implicit columns as the responsive track count changes. Row placement may create native implicit rows.

Grid has no interactive, focus, disabled, loading, validation, appearance, paint, typography, or motion state.

Examples

Featured summary

tsx
<Grid.Root columns={4} gap="3">
  <Card.Root>Activity</Card.Root>
  <Grid.Item columnSpan={2}>
    <Card.Root>Featured report</Card.Root>
  </Grid.Item>
  <Card.Root>Storage</Card.Root>
  <Grid.Item columnSpan="full">
    <Card.Root>Workspace summary</Card.Root>
  </Grid.Item>
</Grid.Root>

Semantic list

tsx
<Grid.Root as="ul" minItemSize="sm" gap="3">
  <li>Design review</li>
  <li>Accessibility review</li>
  <li>Release review</li>
</Grid.Root>
Public contract

API

Start with the public parts and root options below. Components with multiple parts separate each area into its own named subsection.

Root

PropValuesDefault
asdiv, span, section, article, nav, header, footer, main, aside, ul, ol, lidiv
columns112, or responsive object1
minItemSizexs, sm, md, lg, xlunset
gapnumeric factor, explicit CSS value, legacy token, or responsive object0
rowGapsame spacing grammarinherits gap
columnGapsame spacing grammarinherits gap
alignstretch, start, center, end, baseline, or responsive objectstretch
justifystretch, start, center, end, or responsive objectstretch
slotstringgrid
childrenReactNodeoptional

columns and minItemSize are mutually exclusive. Supplying minItemSize selects intrinsic mode; otherwise Root uses explicit mode.

Item

PropValuesDefault
asdiv, span, section, article, header, footer, aside, lidiv
asChildbooleanfalse
columnSpan112, full, or responsive objectunset
columnStart / columnEndgrid lines 113unset
rowSpan112, or responsive objectunset
rowStart / rowEndgrid lines 113unset
alignauto, stretch, start, center, end, baseline, or responsive objectauto
justifyauto, stretch, start, center, end, or responsive objectauto
slotstringgrid-item
childrenReactNodeoptional

On each axis, a span and explicit end are mutually exclusive. A start may combine with a span or end. columnSpan="full" cannot combine with column start/end.

A responsive span is deliberately unanchored and cannot combine with explicit start/end lines. Keep explicit lines static, or let the responsive item auto-place. This prevents stale line geometry when a span changes to or from full.

Set asChild when an existing element should itself be the grid item:

tsx
<Grid.Item asChild columnStart={2}>
  <NavigationMenu.Link href="/services" variant="panel">
    <Surface inset="sm">Services</Surface>
  </NavigationMenu.Link>
</Grid.Item>

asChild requires exactly one React element and cannot be combined with as. Grid classes, placement metadata, native props, events, styles, and the ref are merged onto that element without changing its semantics.

Shared responsibility

Accessibility

Grid adds no role, name, state, keyboard behavior, or focus target. Never add role="grid" merely because CSS Grid is used; interactive grid behavior belongs to Atom DataGrid.

DOM order remains reading and sequential focus order. Item placement never changes it. Dense flow, order, reverse behavior, and responsive visual reordering are deliberately excluded. Choose valid semantic hosts and children and name repeated landmarks.

Use as="ul" or as="ol" when the peer collection is meaningfully a list. Do not add consumer CSS to cancel its native list geometry; Grid owns that normalization for its supported semantic hosts.

Responsive behavior

Intrinsic mode responds to Grid's available inline size without JavaScript or viewport breakpoints. Its min(100%, …) track safeguard prevents the minimum token from forcing page overflow.

Explicit mode accepts Brick's responsive object grammar:

tsx
<Grid.Root columns={{ initial: 1, md: 2, lg: 4 }} gap={{ initial: 3, lg: 8 }}>
  <Card.Root>First</Card.Root>
  <Grid.Item columnSpan={{ initial: "full", lg: 2 }}>
    <Card.Root>Featured</Card.Root>
  </Grid.Item>
</Grid.Root>

Objects require initial and may add sm, md, lg, and xl. The same grammar applies to Root gaps/alignment and unanchored Item spans/alignment. It never changes DOM or focus order. minItemSize and explicit line placement remain static.

Stable visual contract

Styling and tokens

Customization

Use layout props first, then public variables or ordinary local CSS:

tsx
<Grid.Root
  columns={2}
  gap="2"
  style={{
    "--brick-grid-column-gap": "2rem",
    "--brick-grid-row-gap": "0.5rem",
    border: "2px dashed var(--brick-color-accent-border)",
    padding: "var(--brick-space-4)",
  }}
>
  <Card.Root>First</Card.Root>
  <Card.Root>Second</Card.Root>
</Grid.Root>

Paint and outer sizing remain consumer or Surface/Card responsibilities.

Tokens and CSS hooks

Stable Root hooks are .brick-grid, [data-slot="grid"], data-mode, data-columns, data-min-item-size, data-gap, data-row-gap, data-column-gap, data-align, and data-justify.

Stable Item hooks are .brick-grid-item, [data-slot="grid-item"], data-column-span, data-column-start, data-column-end, data-row-span, data-row-start, data-row-end, data-align, and data-justify.

Both parts expose the stable data-slot attribute.

Public variables:

  • --brick-grid-columns
  • --brick-grid-gap
  • --brick-grid-row-gap
  • --brick-grid-column-gap
  • --brick-grid-min-item-size
  • --brick-grid-item-column-start
  • --brick-grid-item-column-end
  • --brick-grid-item-row-start
  • --brick-grid-item-row-end

Advanced reference

Open these details only when you need to inspect DOM ownership, native forwarding, or lower-level composition.

Maintainer resources

Tests, playground evidence, source notes, and release history remain available without crowding the plug-and-play guide.