Skip to main content

The spacing scale

The primitive scale under the named steps and how each density maps onto it.

Version: 3.0.0-beta

Background for the named steps in Overview. You do not use the primitive scale directly, and it is hidden from the Figma variable picker, but you need it to understand why the steps are the sizes they are.

The primitive scale​

The scale starts from one base: index 100 equals 16px. Every other index expresses a fraction or multiple of that base. For example, 50 is half the base and resolves to 8px, while 200 is twice the base and resolves to 32px.

The index is measured in hundredths of the 16px base, so the px value is:

px = round(index × 0.16)

The highlighted 100 / 16px row is the base for the whole scale. The rounding in the formula is why the low end has awkward indices: 1px is 6, not 1.

Convert an index to pixels, not pixels to an index

The formula tells you the pixel value of a known index. It cannot tell you which index the scale uses for a known pixel value, because more than one index can round to the same number. For example, both 12 × 0.16 and 13 × 0.16 round to 2px, but this scale defines 2px as index 12. Use the table to look up an index from a pixel value.

Indexpx
00px
61px
122px
193px
254px
376px
508px
6210px
7512px
8714px
10016px (base)
12520px
15024px
17528px
20032px
22536px
25040px
27544px
30048px
32552px
35056px
37560px
40064px
45072px
50080px
55088px
60096px
700112px
800128px
900144px
1000160px
1100176px
1200192px
1300208px
1400224px
1500240px
1600256px
1700272px
1800288px
1900304px
2000320px
2100336px
2200352px

Two regions, at different resolutions​

  • Below 16px the steps are 1, 2, 3, 4, 6, 8, 10, 12 and 14px, so roughly 2px resolution. This is control-interior territory, and a 4px grid cannot pad a chip or offset an icon precisely enough.
  • From 16px up it is a 4px grid to 64px, then 8px to 96px, then 16px to 352px. Layout territory, where precision below 4px is noise.

How density works​

Each density is a distinct assignment of the names to primitive steps. It is not a multiplier, not a transform: scale(), and Compact is not Comfortable × 0.75.

Each spacing name maps to a smaller primitive in Compact and a larger primitive in Relaxed. The table shows those assignments directly:

StepCompactComfortableRelaxed
spacing.none0px0px0px
spacing.4xs1px2px4px
spacing.3xs2px4px6px
spacing.2xs4px6px8px
spacing.xs6px8px10px
spacing.sm10px12px16px
spacing.md12px16px20px
spacing.lg16px20px24px
spacing.xl20px24px28px
spacing.2xl24px28px32px
spacing.3xl28px32px36px
spacing.4xl36px40px44px
spacing.5xl44px48px52px
spacing.6xl60px64px72px
spacing.7xl72px80px88px
spacing.8xl88px96px112px
spacing.9xl112px128px144px

Some primitive values are not assigned to a spacing name. The difference between densities grows with the scale, from a few pixels for smaller steps to as much as 16px for larger steps.

In the layout band, 4xl to 9xl, each step sits on three adjacent positions of the primitive grid, the way 3xl does. Two consequences of that are deliberate:

  • Primitive 350 (56px) is skipped. 5xl ends at 325 (52px) and 6xl starts at 375 (60px). Every other pair of neighbouring steps from 3xl up shares a primitive, so this is the only gap in the band.
  • 6xl and 8xl are uneven. 6xl is 4px smaller in Compact and 8px larger in Relaxed, and 8xl is 8px smaller and 16px larger. The grid moves in 4px increments up to 64px, 8px up to 96px and 16px above that, so a step that straddles one of those changes is wider on one side.

Corner radius​

Same collection, same one-position-per-density behaviour:

TokenCompactComfortableRelaxed
corner-radius.none0px0px0px
corner-radius.rounded2px4px6px
corner-radius.rounded-outer3px5px7px
corner-radius.pill9999px9999px9999px

rounded-outer is not an independent value. It is defined as rounded plus 1px, so it follows rounded at every density without being maintained separately. The plus-1px mirrors the 1px outline-offset a focus ring uses in CSS, which is the only thing the token is for. See why not to use it.

Where to go next​