The spacing system

Whitespace
is not empty space.

Jan Tschichold, The New Typography, 1928

Ten steps, from things that touch to things that are apart. Every one moves together when the density changes, so a screen is dense or roomy as a whole rather than in pieces. Hover the bars to space them evenly.

01

Ten steps

A spacing scale is the one part of a design system you can print at life size and have it mean exactly what it means on screen. Below is the ladder, drawn at 100 per cent.

It doubles roughly every two steps, which is enough resolution to separate a label from its icon and a section from the next one without offering forty values nobody can choose between. Ten is a number a person can hold.

Each row shows its step twice: once as something and once as nothing. They are the same measurement, and the second one is the half people forget to check.

--space-0
0px @100%  ·  0rem
Flush. Two things that belong to one another
--space-1
2px @100%  ·  0.125rem
Hairline separation. A badge from its glyph
--space-2
4px @100%  ·  0.25rem
Icon to its label
--space-3
8px @100%  ·  0.5rem
Inside a control. Between two chips
--space-4
12px @100%  ·  0.75rem
Between rows in a list
--space-5
16px @100%  ·  1rem
Standard padding. The default for a card or a pane
--space-6
24px @100%  ·  1.5rem
Between groups inside a panel
--space-7
32px @100%  ·  2rem
Between sections on a page
--space-8
48px @100%  ·  3rem
Between major regions
--space-9
64px @100%  ·  4rem
Page margins on a wide screen
02

One setting moves everything

Every size in the product is a rem multiplied by the density setting. Padding, gaps, radii and type all read the same variable, so changing it is not shrinking the text inside the same boxes — it is a denser interface.

Five steps, from −2 to +2, and the app opens at 0. Someone who wants more room moves up, someone who wants more on screen moves down, and the whole interface follows either way, holding its proportions at every step. The range is deliberately short: two notches is enough to matter and not enough to break a layout.

Every pixel figure in this system is quoted at step 0, so the documentation and a default screen agree. A value measured in the inspector is the value in the table.

One formula, and no viewport override. It is tempting to tighten things up when a window is narrow, but a cramped window is already short of room and taking space out of it makes it harder to use rather than easier. Anyone who wants more on screen has the setting. On touch it would be worse than unhelpful: a finger needs a larger target, not a smaller one, so shrinking an interface because the screen is small is exactly backwards.

StepScalingspace-5ui
-20.9014.4px11.7pxtighter, more on screen
-10.9515.2px12.3px
+01.0016.0px13.0pxthe default. Every figure in this system is quoted here
+11.0516.8px13.7px
+21.1017.6px14.3pxroomier
Density

Lapsed buyers

Everyone matching the rules below is added automatically.

Last seenmore than 90 days ago
Ordersat least one
Size12,480 people
:root {
  --fc-scale-step: 0;                                /* -2 … +2, the user's */
  --scaling: calc(1 + var(--fc-scale-step) * 0.05);  /* 0.90 … 1.10 */
}

Density is not a text size. It is how close together a person wants to work.

03

Radius comes off the same ladder

Four corners, each one a step from the spacing scale, so a card's radius and its padding are related numbers rather than two decisions. The fifth is not a size at all — a pill is a shape, and it stays a pill at every density.

--radius-xs4px

Badges, chips, small indicators

--radius-sm8px

Inputs, buttons, menu items

--radius-md12px

Cards, panels, popovers

--radius-lg16px

Dialogs, drawers

--radius-fullpill

Pills and avatars. Not a size, a shape

04

What a step is not

Three things get mistaken for spacing, and keeping them out is what lets ten steps be enough.

Type sizes are not spacing steps. They live on their own ladder, with their own leading and tracking and face. A rung and a gap are different kinds of measurement that happen to be expressed in the same unit.

Layout widths are not spacing steps. A pane that is 720px wide is a layout decision made once for that pane. Putting it on the spacing scale implies it belongs to a progression, and invites someone to reach for the step next to it.

A one-off is not a step. If a value appears once, it is a number in a component, not a token. A scale earns its place by being reused.

05 — What moves

What moves

One scale of forty-nine tokens becomes ten spacing steps, four radii, and two things that were never spacing. This section is here for the migration and comes down once it is done.

TodayBecomesWhy
viewport override--scaling changes at 1536pxgoneEvery dimension jumped 11 per cent at one width, and it shrank phones, where a target needs to grow.
49 size tokensone scale for everythingspace-0 → space-9, plus radiusTen steps for gaps and padding. Type has its own ladder. Fixed dimensions stop pretending to be spacing.
size/1-75, size/2-57px and 10pxgoneNeither is a step in any progression. Both were a value someone needed once.
size/2-75 … size/3-511, 13 and 14pxthe type ladderThese are type sizes living in the spacing scale. They move to the rungs that own them.
size/140 … size/306560px to 1224pxlayout widthsSeven tokens above 400px, each used once or twice. A pane width is a layout decision, not a spacing step.
radius/fixed/md, /lg16 and 20pxgoneDuplicates of radius/lg and radius/xl under a second name.

Nobody building a screen measures anything. They ask for the gap between rows or the padding of a card, and it arrives at whatever density the person reading it has chosen.