Spacing
Overview
Spacing ships no tokens of its own — and that's the point. The
master numeric scale (--scale-0 … --scale-24) was built in Foundation 1 to be the
single source of every dimension, spacing included. So this page doesn't define values; it teaches
how to apply the scale to padding, gaps, and margins.
Where scale.md reads token → use ("here's --scale-4, here's a use"), this page is
the inverse: task → token ("building a card? reach for --scale-5").
Scope: padding, gaps, and margins. Sizing (heights, widths) draws from the same scale but is a separate job — see the note under Tokens.
Principles
- Everything is a scale step. Every gap, padding, and margin comes from
--scale-*— never a raw pixel value. - A 4px rhythm. Because every step is a multiple of 4, the whole UI aligns to one grid without anyone measuring.
- Proximity. Related things sit closer together; unrelated things get more space. Grouping is done with spacing before it's done with lines or boxes.
- Nesting rhythm. Spacing shrinks as you move inward: section > group > component > element. Inner padding should never exceed the gap that separates the container from its neighbours.
Tokens
Spacing adds none. It uses the existing scale tokens from tokens/primitives.css. Reach for a
step by task:
| Building this | Use | px |
|---|---|---|
| Icon-to-label gap | --scale-1 | 4 |
| Tag / badge padding | --scale-1-5 | 6 |
| Small button padding | --scale-2 | 8 |
| Input / button padding | --scale-3 | 12 |
| Default gap between elements | --scale-4 | 16 |
| Card / panel padding | --scale-5 | 20 |
| Gap between form fields | --scale-6 | 24 |
| Space between groups | --scale-8 | 32 |
| Space between page sections | --scale-16 | 64 |
| Gap between major sections | --scale-20 | 80 |
| Page-level breathing room | --scale-24 | 96 |
Spacing vs sizing. This table is spacing (padding, gap, margin). Fixed sizes — a small button's
--scale-10(40px) height, a large button's--scale-12(48px) — draw from the same ladder but are a sizing decision, so they're not listed here.
In Tailwind these map straight to utilities: --scale-4 is p-4 / gap-4 / m-4, --scale-5
is p-5, and so on — tokens and utilities never disagree.
Rationale
Why no spacing tokens? A semantic spacing layer (--space-md → --scale-4) would be pure
indirection. Tailwind already maps p-4 and gap-2 onto scale steps, and Scale's own rules warn
against a parallel ladder. Adding one would be a second thing to learn and keep in sync for zero
gain. The right number of new tokens here is zero — the shared scale doing exactly its job.
Why a task-oriented table? It removes the only real friction in spacing: the "which step?" guess. Naming the common jobs and pinning each to a step makes the consistent choice the easy one.
Why the nesting rhythm? Uniform spacing everywhere flattens hierarchy. Letting space shrink inward — big gaps between sections, small gaps between an icon and its label — is what makes a layout read as structured rather than loose.
Do / Don’t
Do
- Use a
--scale-*step for every padding, gap, and margin. - Pick the step by task from the table; when unsure, round to the nearest step.
- Let spacing shrink as you nest inward, and use proximity to group related items.
Don’t
- Hard-code one-off pixel values (
13px,17px) — snap to the nearest step. - Invent
--space-*aliases — reference the scale directly (Restraint). - Use
--scale-pxfor spacing; it exists for hairline borders only.