Protected

Password required

This work is shared selectively. Reach out at karleeboillot@gmail.com if you need access.

Incorrect password — try again

← Fluent Flex
4 min read

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

22 tokens, one flat list

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

20 tokens, two purposeful tiers

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.

Two spacing scales shown side by side — Component (4px base, 10 tokens from 2px to 28px) and Layout (8px base, 10 tokens from 8px to 96px) — with multiplier labels on each step
Two scales, two intents. The multiplier in the token name makes the pixel value derivable — the name encodes the math.

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.

Token name anatomy diagram showing how gnrc-spacing-component-base-200 breaks into tier (component), scale (base), and multiplier (200 = 2×), yielding 8px
The name encodes the math. You don't need the token value if you understand the naming convention.

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.

Intent Component-tier range Typical use
Tight base-50base-250 (2–10px) Navigation rows, tabs, badges, dense menus
Regular base-100base-400 (4–16px) Most components — buttons, inputs, cards
Relaxed base-400base-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.

Grid Container Columns Gutter Margin
Full 1020px 16 16px 16px
Reading 768px 12 of 16 16px 16px

Breakpoint primitives define when layout behavior can change:

320px 480px 768px 1024px 1366px 1440px 1920px

Looking ahead

What's Next