spacing
Spacing and Density
Space is a grouping signal, not decoration — distance is how an interface says "these belong together and that one does not", and it says it before any border, background or label is read. So the default posture is: one scale for the whole project, every gap a step on it, and gap on the parent rather than margins on children. When a value feels wrong, the fix is almost always to change the ratio between two gaps rather than to nudge one of them; an interface reads as sloppy when nested gaps are similar, not when they are large. The sibling layout decides which regions exist and how they stack — if the open question is what goes where, that is layout, and this skill starts once the regions are settled. The other near-neighbour is ui-polish: nudging a single glyph inside its own box (a play triangle, an asymmetric caret) is theirs; balancing the space around a group is here.
Find the project's scale before writing a single value. Look for theme.spacing or a Tailwind --spacing setting, a --space-* token block, an SCSS $space map, or — most commonly — an implicit scale you can read off the existing components. Adopt it exactly, including its quirks. A 18px gap in a codebase built on multiples of 4 is more damaging than a slightly wrong step from the real scale, because it teaches every future contributor that values are freehand. If the project has no scale, introduce the one below as tokens and convert the file you are already touching, not the whole codebase.
Quick Reference
| Topic | File |
|---|---|
| You need the actual numbers — a step value, its Tailwind class, a component's padding recipe, or the comfortable/compact/dense row specs | Open scale.md whenever a concrete value or a density table is required rather than a rule. |
Core Principles
-
Ship one scale and make every gap a step on it. A closed set makes a wrong choice visible; an open set makes every choice arguable. The default is
4 · 8 · 12 · 16 · 24 · 32 · 48 · 64 · 96px, expressed as tokens. Exception: a single optical correction (-1px,2px) may sit off-scale where it fixes an alignment illusion, and it must carry a comment saying so — otherwise the next person "rounds it to the scale" and reintroduces the bug. -
Steps go linear near zero and geometric above it.
4pxis a large relative jump at small sizes and an invisible one at large sizes, so a purely linear or purely geometric scale fails at one end. Below16pxthe increment is4px; above16pxeach step is roughly1.5×its predecessor. Exception: a project already on a strict 8px grid — keep it and do not rebase; a half-migrated scale is worse than either scale.