Spacing

Closer means more related. Space groups. Air lets the eye scan. Do not invent a gap. Pick a role.

Two layers

Primitives are the raw steps on the ladder. Semantic roles are what you use in views. Raw pixels are an exception or a mistake.

  1. Primitives. Seven steps: 4, 8, 16, 24, 48, 80, 120. They exist so a value is not written twice.
  2. Roles. tight, related, grouped, and the rest. Use these in layout. If you write a raw margin or padding in a view, you are in an exception that needs a note, or you made a mistake.

The ladder

Each role maps to one primitive. The names describe relationship, not decoration.

RolepxUse
tight4Caption under a chip, kicker under a title, tight pairs.
related8Heading to lede, list items, labels after chips, table cells.
grouped16Paragraphs in a section, swatch rows, pulse plates.
inset24Subsection heading top, specimen stack, logo to nav.
section48Between doc sections, nav groups, mobile sidebar padding.
gutter80Page gutter between sidebar and main.
canvas120Top and bottom canvas padding on docs pages.

Bar specimen

RolepxBar
tight4px
related8px
grouped16px
inset24px
section48px
gutter80px
canvas120px

Composition rules

Spacing is about what belongs together. These rules keep rhythm consistent across pages.

  1. Heading owns its paragraph. Use related between a title and the lede that follows.
  2. Paragraphs in a section. Use grouped between body paragraphs.
  3. Next section. Use section before a new h2 block.
  4. Figure owns caption. Use tight between a chip and its caption.
  5. Heavy figure, then next section. A pulse plate or large swatch row already carries weight. The section margin provides the air before the next heading.

What this site uses

Root docs, the letter, and the nav use these seven roles. There is no second set of gaps for chrome versus content.

On the web, roles map to --space-* CSS variables in globals.css. The catalog lives in lib/root-tokens.ts.

iOS

The same seven names exist as points in NTCSpace. Space next to text uses @ScaledMetric so Dynamic Type can scale it. There is no second iOS ladder.

Open questions

Keep the set small. A new gap is either a missing role or a mistake. If you reach for 12, 20, or 32, stop and pick the nearest role.

Source: lib/root-tokens.ts for the catalog; CSS --space-* for web; optional Swift NTCSpace for native.