Skip to content

Grid and layout system

Layout is content-width first: components reflow from the page content column (and nested containers), not only from viewport breakpoints.

Content tokens

Token roleTypical value
Content max width~1000px — shell and header align to this
Prose max width65ch — reading measure for body copy
Named page containere.g. scout-pagecontainer-type: inline-size on the main column
Two-column container querye.g. @container … (min-width: 720px) — main + sub-nav side-by-side

Viewport media

A small mobile-first scale (e.g. 480 / 640 / 768 / 1024 / 1280) as Griffel @media keys. Use viewport media for chrome (main nav desktop vs burger). Prefer container queries for in-page grids.

Nav desktop media often combines min-width with orientation so portrait tablets keep the burger menu.

Equal tiles — auto-fit grid

A shared component (here: AutoFitGrid) implements CSS grid auto-fit tracks that wrap by available width:

tsx
<AutoFitGrid minItemWidth="160px" justifyItems="stretch" as="ul">
  {/* items */}
</AutoFitGrid>
Prop ideaUse
minItemWidthWrap threshold
gapOverride fluid default gap
justifyItemscenter for logos; stretch for form fields
asul / ol for lists

Good for: logo strips, field pairs, footer nav, card strips.
Not for: unequal main + sidebar.

Section columns — row + main + side nav

A layout module provides:

PrimitiveRole
RowStack by default; row at two-column container query
Main / double columnWider primary content
Sub-nav columnSection links; order flips when stacked vs side-by-side

Image + copy splits

A fifty-fifty layout with its own container-type so the split reflows from host width.

Decision tree

Frontend Corner — agent ops, tooling, and decision records