Fluent Flex · Chapter 03
Spacing
22 tokens duplicated by axis, with nudge values that existed only because the underlying scale wasn't mathematical. Rebuilt into two purpose-built tiers — component and layout — where the pixel value is derivable from the token name alone.
22
Spacing tokens before — 11 unique values duplicated across two axes
20
Spacing tokens after — 10 component + 10 layout, no axis duplication
0
Nudge values in the new system — every step is a clean multiple of the base
Background
The Spacing System Before Flex
V9 spacing contained 22 tokens: 11 vertical and 11 horizontal, using the same 11 values duplicated by axis with no semantic distinction. The axis duplication didn't change the decision logic — direction doesn't change whether 8px is right for a given space.
The values tell the story: 0, 2, 4, 6, 8, 10, 12, 16, 20, 24, 32px. The "Nudge" values — 6px as SNudge, 10px as MNudge — are a tell. A derived system doesn't need nudges. Nudge values exist because the underlying scale wasn't mathematical; designers needed in-between steps that the scale didn't provide cleanly.
Component padding, internal spacing, and layout spacing also all lived on the same flat list — forcing designers to make judgment calls about which value was appropriate for which context, rather than applying a structural rule.
Impact
Before & After
V9 — Before
11 values duplicated across vertical and horizontal axes. Nudge values (6px, 10px) signal a non-derived scale. No distinction between component-internal and layout-level spacing.
- Values: 0, 2, 4, 6, 8, 10, 12, 16, 20, 24, 32px
- Component and layout spacing on the same flat list
- Axis duplication with no semantic benefit
- AI couldn't infer appropriate spacing from context
Fluent Flex — After
10 component tokens (4px base) + 10 layout tokens (8px base). No axis duplication. No nudge values — every step is a clean multiple. Plus a formal 16-column grid system.
- Component scale: 2px–28px (4px base × multiplier)
- Layout scale: 8px–96px (8px base × multiplier)
- Grid: 16-column full (1020px) + 12-column reading (768px), 7 breakpoints
- Reaching for a layout token inside a component is a structural signal
Architecture
Two Bases, Two Tiers
Spacing means something different depending on where it lives. The space inside a button is a different kind of decision from the space between two page sections — they have different relationships to their surrounding elements, different density expectations, and different consequences when they're wrong.
Two tiers, two base units:
Component scale — 4px base
10 tokens covering internal gaps and padding within controls. The 4px base aligns with
icon grids and interactive target sizes. Token names encode the multiplier:
-base-200 is 2× the base (8px). The pixel value is derivable from the
name — no lookup needed.
Range: 2px through 28px. The scale covers everything from tight label-to-icon spacing to the internal padding of a large input.
Layout scale — 8px base
10 tokens covering section margins, page structure, and the space between regions. The 8px base creates comfortable visual breathing room at the layout level. Using a layout token inside a component is now a detectable structural error — the tier distinction is a guardrail, not just a naming convention.
Range: 8px through 96px. The scale covers card padding through full-page section breaks.
Naming
Names That Encode the Math
The naming convention is the system's most visible design decision. In V9,
spacingVerticalS tells you the axis and a vague size. In Flex,
--gnrc-spacing-component-base-200 tells you the tier (component),
the scale (base), and the multiplier (200 = 2×). The pixel value — 8px — is
derivable from the name without a lookup table.
This is what the hub means by "token names encode the math." A designer, engineer,
or AI agent reading the token name knows not just the value but the relationship:
-base-400 is twice -base-200. The scale is auditable
from the names alone.
Density intent
Tight, Regular, Relaxed
The same multiplier reads differently depending on where it lands on the scale. These intent labels help reason about density without prescribing exact values — a component can use any tier, and the choice is about the desired feel of the surface.
base-50 – base-250 (2–10px) Navigation rows, tabs, badges, dense menus base-100 – base-400 (4–16px) Most components — buttons, inputs, cards base-400 – base-700 (16–28px) Popovers, large containers, generous surfaces
The ranges overlap by design — base-400 (16px) sits at the upper edge of
Regular and the lower edge of Relaxed because the same value carries different weight
in different contexts. Pick the multiplier that produces the right visual result.
Related
The Grid System
The layout spacing tokens and the grid structure are part of the same system document. A 16-column full grid (1020px container) for rich page layouts, a 12-column reading grid (768px container) for content-focused views. 16px gutters between columns, 16px margins on each side.
Breakpoint primitives define when layout behavior can change:
320px 480px 768px 1024px 1366px 1440px 1920px Looking ahead
What's Next
- Spacing tokens as direct input to AI-generated layout specs. With a mathematical foundation and role-encoded names, a model can select the correct spacing tier without guessing — component padding vs. layout gap is inferable from context.
- The two-scale structure is extensible: if a third tier emerges (e.g., a micro-density mode for data-dense surfaces), it slots into the same naming convention without restructuring the existing scales.
- Cross-platform spacing parity — Web, iOS, and Android derive from the same base unit logic, so the intent translates even when the platform rendering differs.