Grid is a layout host for tokenized column and row tracks. It does not carry paint—put background, border, and content on Box (or other primitives) inside cells. Use template={GridTemplate.*} for product layouts instead of consumer grid-template-columns. Pair with GridItem when a child spans multiple tracks.
For one-dimensional flex inside a cell (scroll hosts, toolbars), use Box / FlexBox item (FlexItem, alignSelf).
Queue metric tokens resolve to 14.4375rem (standard) and 21.0625rem (ECT) at a 16px root.
Runtime column count
Use columns when the column count comes from runtime state (for example a density selector). Optional trackMin and trackMax use the same LayoutSize and Breakpoint tokens as Box. Pair with justify={GridJustify.SafeCenter} when tracks should centre when they fit and start-align when they overflow.
Auto-fill with a column cap
Use autoFill when the column count should follow container width rather than a fixed N. Pass trackMin (LayoutSize); add maxColumns to limit how many tracks may appear. GridAutoFill.Fill keeps empty tracks; Fit collapses them. Column gap participates in the cap through the same gap prop.
For the fixed gallery minimum, keep template={GridTemplate.AutoFillMinItem}.
Scale descendants to fit
Use contentScale when measured density should reach descendants without scaling the grid host. Grid writes --ds-content-scale (same ZOOM_STEPS as zoom and toZoomStep). Descendants apply it in module CSS, typically with zoom: var(--ds-content-scale, 1) and a compensated max-inline-size. Nested Grid hosts inherit the nearest ancestor value until another grid sets contentScale. Host zoom scales the entire subtree and reflows the host box; it does not replace per-item scaling.
Width-responsive spans
columnSpan and rowSpan on GridItem (and on a subgrid Grid) take a fixed GridSpan (One to Twelve, or Full) or a GridResponsiveSpan: initial applies at every width, and each GridBreakpoint key replaces it once the nearest container is wider than that breakpoint (1080, 1280, 1600, 1920, 2560, 3440px). The largest matching key wins, and a collapsing parent still forces one track, so pair spans with collapseBelow to reflow in narrow containers. Wrap the grid in a Box with containerType={ContainerType.InlineSize}.
Item alignment
alignSelf (GridAlignSelf) and justifySelf (GridJustifySelf) on a GridItem or nested Grid move that one child within its cell and override the grid's align for it only.
Area layouts
defineGridAreas builds a typed layout: GridTrack columns and rows (tokens, fr tracks or sizing keywords, or { space } steps), a matrix of area names, and below layouts for narrower containers keyed by the collapseBelow widths. Children take area={layout.areas.<name>}; a name the layout does not declare fails typecheck. GRID_AREA_PRESETS holds the approved layouts as starting points: mainAside, asideMain, headerMainAside, headerMainFooter.
Reading order. DOM order must match the logical reading and focus order, which is the order of the narrowest (single-column) layout. Area layouts may rearrange children visually only in ways that keep that order sensible; they never change what a screen reader or the Tab key meets first. defineGridAreas records the order as readingOrder; put the children in that order.
Subgrid
A nested Grid normally sizes its own tracks. With subgrid, its children sit on the parent's tracks instead, so groups line up with each other. The nested Grid must be the parent's grid item, so the span goes on it: columnSpan for GridSubgrid.Columns, rowSpan for GridSubgrid.Rows, both for GridSubgrid.Both. The types require the span and reject own tracks (template, rows, collapseBelow) on an adopted axis.
GridSubgrid
Adopts
Requires
Columns
Parent column tracks
columnSpan
Rows
Parent row tracks
rowSpan
Both
Parent column and row tracks
columnSpan and rowSpan
Gap. Leave gap unset on an adopted axis to keep the parent's gutter. A set gap replaces the gutter inside the subgrid, and its children still start on the parent's track edges. Paint. Grid has none, so a subgridded card puts its surface on the Box parts inside it.
Form label and field columns
Each section is a column subgrid spanning every parent column, so the labels in both sections share the parent's FitStartMain leading track and every input starts on the same edge. The parent's column gap of 8 is the label-to-control gap.
Card rows
Each Card is a row subgrid spanning three parent rows, one per slot, so headers, content and footers share rows across the cards and each card keeps its surface, radius and padding. A taller header or longer content moves that row for every card. AutoFillMinItem adds and drops columns with the available width, so the cards reflow at high zoom.
Flex item vs Grid
Pattern
Use
Column ratios (2:1, 3:1, ten equal tracks)
Grid + GridTemplate
Fixed metric column + two flexible peers on queue boards
QueueMetricsStandard / QueueMetricsEct
Flex row with one scrollable child
FlexBox + item={FlexItem.FillScroll}
Cross-axis override on one flex child
alignSelf on Box / FlexBox
Before and after
The previews below mirror Grid stories in Storybook.