2026-09-21 · 7 min · By Alcott Dube
How to use spacing tokens with a 4-point spacing system
I use a four-point spacing scale, shared layout rules and a small exception policy to keep design files and production layouts from gradually drifting apart.

I keep layouts consistent by defining spacing tokens in multiples of four, assigning them to repeatable layout relationships, and using the same values in design and code. I allow exceptions for optical alignment and external constraints, but keep them local and documented rather than expanding the scale for every awkward component.
Build a spacing token scale from a 4-point grid
I start with eight values: 4, 8, 12, 16, 24, 32, 48 and 64. Every value is divisible by four, but the scale deliberately skips some steps. A four-point system doesn't require a token for every multiple. It needs enough choices to express hierarchy without making 20 versus 24 a fresh debate on every screen.
For a web product, I might define these as rem values, with 4 pixels represented by 0.25rem at a 16-pixel root size. That relationship changes when the root size changes, which can be useful for scaling. I document the unit policy explicitly. I don't treat web pixels and platform-specific logical units as interchangeable implementation instructions.
Material Design's spacing guidance uses an eight-unit foundation with four-unit spacing for smaller elements. Carbon publishes a broader scale that includes a two-pixel step. I borrow the principle of a deliberate scale, not every value. For spacing system design tokens, a smaller starting set makes accidental differences easier to spot and intentional differences easier to explain.
Separate spacing values from layout decisions
A scale answers how much space is available. It doesn't answer where each value belongs. I separate raw tokens, such as space-4 and space-16, from a few named roles, such as field-label-gap or card-padding. The raw layer holds the values. The role layer records decisions that should survive a component redesign or a change in density.
I only add a role when it describes a repeated relationship with a reason to change independently. Card padding qualifies if cards appear across the product. A one-off gap beside an illustration probably doesn't. Giving every margin its own alias creates a second system to maintain without adding much control over the first.
For example, I might map field-label-gap to 8, form-field-gap to 24 and card-padding to 24. Two roles can share a value without becoming the same decision. If compact cards later need 16, I can change that mapping without squeezing every form. I record both the current value and the intended relationship in the component documentation.

Use spacing to make grouping visible
I assign spacing from the inside out. First comes the relationship between a label and its control, then the relationship between fields, then the separation between form sections. A practical starting point is 8, 24 and 48 respectively. Those aren't universal defaults. They're a testable hierarchy: related things sit closer together than separate groups.
Consider a settings page with three sections. If every vertical gap is 16, the page can look tidy while saying very little about its structure. I would keep each heading close to its explanation, place the fields beneath that introduction, and give the next section a noticeably larger interval. The tokens should describe grouping, not merely satisfy arithmetic.
I check this with realistic content before approving the pattern: a two-line label, a validation message and a paragraph that wraps across several lines. Equal token values don't guarantee equal visual rhythm when text blocks have different heights. I adjust the layout relationship before adding another spacing value to compensate for content I hadn't tested.
Keep spacing tokens consistent in design and code
I treat the token definitions as a shared contract. In the design file, padding and gaps use bound variables rather than typed values. In code, those same decisions reference tokens rather than copied numbers. Matching names help, but matching values, units and intended use matter more. A variable called card-padding is useless if its definitions disagree.
I also give each gap one owner. In a vertical stack, the parent can own the gap between children. The children shouldn't quietly add bottom margins as well. A 24-pixel stack gap plus an 8-pixel child margin produces 32 pixels, and both values may be valid tokens. Token compliance alone won't catch that layout error.
During handoff, I inspect the behaviour rather than just the measurement labels. I want to know which container supplies padding, which parent controls sibling spacing and what happens when an item disappears. For repeated components, I put those rules into the component itself. Otherwise, each screen becomes another opportunity to rebuild the same relationship slightly differently.
Change spacing for responsive layouts and density
I don't halve every gap on a narrow screen. Small relationship gaps often stay the same while outer gutters and section spacing shrink. For example, field-label-gap can remain 8 while page padding changes from 32 to 16. That preserves the internal grouping without spending scarce horizontal space on desktop-sized margins.
I define those changes through layout roles or explicit responsive rules, not by changing the raw space-32 token to mean 16. A primitive value needs to remain dependable wherever it's used. If the same token silently changes meaning at a breakpoint, a developer can't predict its effect from the component definition alone.
Density is a separate decision. A compact data table may need less cell padding than a reading view, even at the same viewport width. I test density with wrapped labels, enlarged text and usable interaction areas. Reducing visible space mustn't make controls difficult to operate. I keep the number of density modes small because each mode adds another set of behaviours to verify.
Know when to break the 4-point spacing system
I allow an exception when the grid produces a worse result for a specific, explainable reason. Optical alignment is the common case: an asymmetric icon can look off-centre inside a mathematically centred box. I might shift the artwork by one pixel while leaving the component's padding and interaction area on the established scale.
External constraints can also justify a local value. An embedded third-party element may have dimensions I can't control. I contain the adjustment in its wrapper and document the dependency. I don't add a global space-13 token because one integration needs 13 pixels. A local repair shouldn't become a tempting option everywhere else.
I don't force borders, letter spacing or every line height onto the spacing scale either. Those properties solve different problems. Before accepting an off-scale gap, I check for default browser margins, unexpected line height, transparent space inside an asset and duplicated padding. A genuine exception survives that inspection; an implementation mistake gets corrected at its source.
Audit spacing drift without redesigning every screen
I start with one representative flow rather than the entire product. I inventory its gaps and padding, group near-matches, and inspect why they differ. Values of 15, 16 and 17 around otherwise identical cards are candidates for consolidation. A 12-pixel icon gap and a 16-pixel paragraph gap aren't automatically a problem just because they're close.
I track three things: unexplained off-scale declarations, repeated relationships with conflicting values, and approved exceptions without an owner or reason. These reveal different failure modes. Counting token usage alone can reward a screen that uses approved values in the wrong places. I compare rendered layouts as well as inspecting declarations and design variables.
I fix the shared component first, then check the screens that consume it with long content and narrow widths. I leave unrelated local layouts alone unless the audit reveals a real inconsistency. My maintenance rule is simple: a new spacing token needs a recurring use case that existing values cannot serve. One uncomfortable screenshot isn't enough evidence.
Questions people ask
Should I use a 4-point or 8-point spacing grid?
I use four-point increments when components need choices such as 4 and 12 alongside larger gaps. An eight-point foundation is useful for broader layout rhythm, and I can keep both within one scale.
Should spacing tokens use pixels or rem?
For web work, I use rem when spacing should follow the root font size and pixels when a fixed measurement is intentional. I document that choice rather than mixing units without a rule.
How many spacing tokens should a design system have?
I start with around eight values and test them against representative screens. I add another only when a recurring layout need cannot be served well by the existing scale.
Can I use spacing values outside the token scale?
I allow local exceptions for optical corrections or constraints outside my control. I record the reason beside the implementation and avoid turning a one-off adjustment into a global token.