Skip to main content

Learning Track

Filter content by your role to see the most relevant sections

Layout Foundations

Structure responsive interfaces with tokenized containers, breakpoint scales, and flow patterns: how width, reading measure, and adaptation points become system decisions instead of per-screen guesses.

Darian Rosebrook
Staff Design Technologist, Design Systems Architect
Expertise:Design Systems, Layout, Responsive Design

Why This Matters

Layout is where design systems quietly die. Color and typography degrade gracefully when improvised; layout does not—every ad-hoc container width and magic breakpoint compounds into a product that behaves differently at every size, and no one can predict where it breaks. Tokenizing layout means the interface's structural decisions—how wide content may grow, where adaptation happens, how flows re-order—have names, owners, and review.

The second reason is harder to see: layout tokens encodeusability research, not just taste. The width where a line of body text stops being comfortable, the viewport where a two-pane workspace stops working, the measure that keeps reading effortless—these are findings. When they live in tokens, the product inherits them everywhere; when they live in per-screen CSS, every new screen re-runs the experiment with worse data.

This page covers layout as structured in this repository: layout.container widths, the dimension.breakpoint scale, control sizing composed from spacing, and the flow patterns that hold it together.

Core Concepts: Containers, Breakpoints, Measure, Flow

Containers Set the Walls

The core layer defines five content widths in ui/designTokens/core/layout.tokens.json:

// layout.container (values)
sm: 640px   md: 768px   lg: 1024px   xl: 1280px   xxl: 1536px

A container token answers one question: how wide may content grow here? Pages pick a container the way components pick a variant—by content type, not by viewport greed. Long-form reading wants a narrow container; data tables want a wide one; dashboards want the widest. The token exists so that "article width" is one decision made once, not a max-width re-chosen per page.

Breakpoints Mark Adaptation Points

Breakpoints are a different scale with a different job—where thestructure changes—and they live in dimension.tokens.json:

// dimension.breakpoint (values)
sm: 640px   md: 768px   lg: 1024px   xl: 1440px
xxl: 1536px  xxxl: 1920px

Note the deliberate asymmetry: breakpoint.xl is 1440px while container.xl is 1280px. They are not misaligned by accident—containers cap content width at a readable measure, while breakpoints fire structural changes at viewport widths where layouts actually need to reorganize. Collapsing them into one scale is the classic error: it forces reading widths to jump whenever structure does. Two scales, two jobs.

The working rule for both: breakpoints are mobile-first min-width boundaries, and a layout that needs more than three of them is usually doing the wrong kind of adapting—discrete jumps where continuous flow would serve better.

Measure Is a Reading Constraint

Between container and breakpoint sits the typographic concern that justifies both: line length. Comfortable reading measure is roughly 45–75 characters; the container scale's values keep body text inside that range at each step when paired with the typography scale. This is why container widths are system decisions—squeeze the measure and comprehension drops measurably; stretch it and eye return-saccades fatigue the reader. A container token is a usability floor expressed as a width.

Controls Compose from Spacing

Layout's smallest unit—the control—gets its structure from the spacing scale, not its own numbers. The semantic layer composes it explicitly through control.size:

// ui/designTokens/semantic/control.tokens.json (excerpt)
"control": {
  "size": {
    "sm": { "height": "{spacing.size.07}",      /* 24px */
           "paddingX": "{spacing.size.03}",
           "paddingY": "{spacing.size.02}" },
    "md": { "height": "{spacing.size.08}",      /* 32px */
           "paddingX": "{spacing.size.04}",
           "paddingY": "{spacing.size.03}" },
    "lg": { "height": "{spacing.size.09}",      /* 48px */
           "paddingX": "{spacing.size.06}" }
  }
}

Control heights are spacing steps (24/32/48), which is why rows of controls align with the gaps around them: everything is arithmetic on one scale. The 48px large control also pairs with the accessibility floor—tapTargetMin at 44px fits inside it without pseudo-element extension.

Flow Over Position

The system's layout defaults are flow-based: block flow, flex row/column, and CSS grid—never absolute positioning for document content. Flow layouts reflow at breakpoints by changing direction and wrapping, not by re-specifying coordinates. That constraint is what makes a tokenized system responsive at all: a layout expressed as flow plus container plus a few breakpoint overrides adapts continuously between the discrete adaptation points.

System Roles: Where Layout Decisions Land

Design Impact

Designers own the container choice per content type and the re-organization at each breakpoint—the wireframe-level decisions of what stacks, what wraps, what hides. The Figma counterpart is auto-layout with the same scale values, so a frame's constraints and the CSS that implements them are the same statement.

Engineering Impact

Engineers own the plumbing: container utilities reading layout.container.*, media and container queries keyed to dimension.breakpoint.*, and the discipline that new structural CSS lands as flow changes, not coordinate overrides.

Accessibility Impact

Accessibility owns the reflow guarantee: at 400% zoom (a 320px effective viewport), content must reflow to a single column without horizontal scrolling—WCAG 1.4.10. Breakpoints and containers make that testable: if the layout only works above 768px, the token scale has been bypassed somewhere.

Design & Code Interplay

In the design tool, layout tokens appear as named frame widths and constraint sets: article frames at the reading container, table frames at the wide one, and auto-layout gaps drawn from the spacing scale. The designer-facing rule mirrors code: pick a container by content type, let frames fill it, and express responsive behavior as re-flow constraints rather than re-positioned copies per breakpoint.

The review question that keeps the two sides synchronized: "which container is this?"—the same shape as "which token is this color?" A layout that cannot name its container is a layout the system cannot vouch for.

Applied Example: An Article Page That Reflows

Ship one layout end to end: an article page with a title, body, and a related-links rail.

  1. Pick the container by content: long-form reading → the reading container ( layout.container.md, 768px keeps body text in measure). Not the viewport, not the widest wall available.
  2. Flow first: title, body, and rail all in block flow with spacing-scale gaps. On small screens this is already the correct layout—nothing to override.
  3. One structural breakpoint: at dimension.breakpoint.lg (1024px), the rail moves beside the body as a two-column grid. The article's reading column keeps its measure because the grid's content column, not the container, caps the prose width.
  4. Prove reflow: at 320px effective width the page is single-column, no horizontal scroll—WCAG 1.4.10 holds because every structural rule was a flow change.
  5. Reuse check: the same rail component dropped into a dashboard (wide container) adapts via its own container query, untouched.

The whole page is three token references, one breakpoint, and flow. That is what a layout system buys: pages assembled from decisions already made.

Constraints & Trade-offs

  • Fixed container steps vs fluid width: five container widths are predictable and readable but never perfectly fill odd viewports; fully fluid layouts fill everything and control nothing. The compromise here is fluid-below, capped-above: content is 100% wide until its container token caps it.
  • Six breakpoints vs component-driven adaptation: page-level breakpoints are simple and coarse; container queries are precise but shift testing burden onto every host context. The system uses both deliberately: breakpoints for page structure, container queries inside components.
  • Two width scales vs one: keeping containers and breakpoints separate doubles the vocabulary but lets reading measure and structural change vary independently—the 1280/1440 xl divergence is a feature.
  • Flow discipline vs pixel control: refusing absolute positioning sacrifices pixel-perfect art direction for reflow guarantees. Escapes exist (decorative overlays) but are content-free by rule.

Common Pitfalls & Failure Modes

1. Magic viewport numbers

/* Bad: A breakpoint nobody approved */
@media (width >= 1180px) { ... }

/* Good: The tokenized scale */
@media (width >= var(--core-dimension-breakpoint-xl, 1440px)) { ... }

Off-scale breakpoints fragment testing: every magic number is a size nobody checked for reflow, zoom, or overlap.

2. Container greed

/* Bad: Everything stretches to the viewport */
.article { max-width: 100%; }

/* Good: Content type picks the container */
.article { max-width: var(--core-layout-container-md, 768px); }

3. Positioning document content

/* Bad: Coordinates for content */
.heroTitle { position: absolute; top: 120px; left: 60px; }

/* Good: Flow + spacing; overlays stay decorative */
.heroStack { display: grid; gap: var(--core-spacing-size-06); }

4. Re-specifying layouts per breakpoint

When each breakpoint rewrites the layout instead of adjusting flow, every size is a new layout to test and drift is guaranteed. The repair is the same as color's: express the layout once in flow, adapt with the minimum override.

Layout System Health Metrics

Layout health is auditable from the stylesheets alone—no rendering required for the first two signals:

Signal 1: Breakpoint discipline

  • Healthy: every @media width condition references a tokenized breakpoint; a grep for @media plus raw pixel values returns only the token fallbacks.
  • Warning: one or two magic numbers survive ("the 1180px hero"), each an untested size that will surprise a future viewport.
  • Critical: media queries outnumber token references—the layout re-specifies itself per size, and each query is a layout nobody reviews.

Signal 2: Flow integrity

  • Healthy: document content is positioned by flow and grid only; absolute positioning appears exclusively in decorative overlays and the hit-area pseudo-elements.
  • Warning: coordinate patches accumulate on one screen—each an apology for a flow that almost worked.
  • Critical: content blocks with hard coordinates; the reflow guarantee is already broken, and zoom mode is the next place it will be discovered.

Signal 3: Reflow proof

  • Healthy: the e2e walk at 320px effective width shows single-column, no horizontal scroll, on every template; the WCAG 1.4.10 guarantee is a test, not a hope.
  • Warning: reflow holds on marketing pages but fails in app surfaces (tables, toolbars)— exactly where density tempts shortcuts.
  • Critical: any horizontally scrolling content at the floor width—an immediate defect with a criterion number attached.

Migration Strategy: From Positioning to Flow

Layout migrations change behavior more visibly than spacing ones, so the strategy front-loads safety:

  1. Inventory the coordinates: every position: absolute/fixed on content, every fixed width on text containers, every magic media query. Tag each: decorative (keep), hit-area (keep), content (migrate).
  2. Rebuild in flow beside the original: for each migrated screen, construct the flow/grid version behind a flag; screenshot-diff against the original at the tokenized breakpoints—rebuilding in place and "fixing later" is how layouts regress silently.
  3. Adopt the two-scale rule: containers by content type (the named widths), structure changes only at tokenized breakpoints; the audit from step 1 tells you which magic numbers were secretly each of these.
  4. Prove reflow before cutover: the 320px walk on the new version is the exit criterion—a migration that ships without reflow proof has traded visible drift for invisible exclusion.
  5. Flip the flag per surface: each screen's cutover is independently revertible; the coordinate version is deleted only when its surface has been stable through a review cycle.

Real-World Case Studies

Case 1: The landing page that couldn't zoom

A hero built on absolute coordinates looked flawless at 1440px and shattered at 400% browser zoom—the three-column text became a 20px-wide strip. The rebuild was the flow version this page teaches: grid with a measure-capped column, one structural breakpoint, container queries for the reusable badge row. The visual result was pixel-similar at every designed size and reflowed below them; the accessibility finding closed with the commit.

Case 2: The two scales that got merged

A team "simplified" by pointing container.xl at the breakpoint value (1440px) so one number ruled both. Within a quarter, reading pages showed 90-character lines—the container was following structure instead of measure, exactly the collapse the two-scale rule exists to prevent. The restore was one value; the lesson was the rule's rationale surviving contact with a real codebase.

Case 3: The sidebar that hid from keyboards

A visually-ordered layout (sidebar first) was built by re-ordering the DOM to match a sketch; screen reader users got navigation before content on every page, and the e2e reading-order check flagged the divergence. Grid placement restored the correct DOM order with the same pixels—styling reclaimed its job from structure.

Verification Checklist

Additional Resources

  • Grid Systems — columns and gutters built on these containers and breakpoints (/blueprints/foundations/grid)
  • Spacing & Sizing — the scale that control sizes and gaps compose from (/blueprints/foundations/spacing)
  • WCAG 1.4.10 reflow — the 320px reflow requirement (https://www.w3.org/WAI/WCAG21/Understanding/reflow.html)
  • The sources — ui/designTokens/core/layout.tokens.json, ui/designTokens/core/dimension.tokens.json, ui/designTokens/semantic/control.tokens.json

Related Concepts

Reflection Questions