In a food-delivery app's design system, an audit finds 37 distinct spacing values across restaurant cards and menu screens; how do you bring spacing back onto the scale?
answer
- count before you change
- drift, cause or missing step?
- borders and line heights hide causes
- fix components before screens
- tokens plus an automated check
basics
~20 sInventory and classify the values first: near-miss drift, systemic causes such as borders or off-grid line heights, deliberate exceptions, and genuinely missing steps. Fix shared components before screens, replace raw numbers with spacing tokens, and add checks so drift cannot return.
solid answer
~50 sStart by **measuring**: extract spacing values from code and design files, count how often each appears, and note where. Then **classify**: most will be near-miss **drift** (14 and 15 meaning 16), some have **systemic causes** (a 1-unit border added to a 12 inset gives 13; a 22.5 line height pushes everything below off the grid), a few are deliberate **optical adjustments** worth documenting, and a value used heavily across teams may be a **missing step** to add through the normal change process. Write an old-to-new mapping, fix **shared components first** (restaurant card, menu row), then screens, replacing raw numbers with **spacing tokens**. Review every change visually rather than bulk-replacing blindly, and add guardrails: spacing presets in the design library and an automated check that flags raw values in code. Track the distinct-value count down over time.
go deeper
Recall that spacing should reference scale steps as tokens rather than raw numbers, and that off-scale values are a signal to investigate.
Explain the systemic causes of off-scale values, such as border arithmetic, fractional line heights and components carrying outer spacing.
Demonstrate the whole cleanup: inventory, classification, a mapping, components before screens, visual review and guardrails that stop drift returning.
Discuss how to fund and sequence a cleanup across many teams, and when a heavily used off-scale value should change the scale itself.
## Measure before changing anything Thirty-seven distinct values is a symptom; the causes decide the fix. Start with an inventory: 1. Extract every spacing value from the code, and sample the design files for the same screens. 2. Count how often each value appears and where: which components, which screens, which teams. 3. Sort by frequency. Typically a handful of values cover most uses and a long tail appears once or twice. This turns a vague sense of messiness into a list you can reason about, and gives a baseline to show progress against. ## Classify every value | Class | Example in a food-delivery app | What to do | |---|---|---| | **Drift** | 14 and 15 between a dish name and price, meant to be 16 | map to the nearest step | | **Border arithmetic** | 13 and 17 inside cards with 1-unit borders | treat the border as part of the inset; map to 12 or 16 | | **Off-grid text** | values ending in .5 below a 22.5-unit line height | fix the type style's line height, then the space | | **Outer spacing on components** | a card that adds 20 below itself, doubling with the list's 16 | remove it; let the parent own the space | | **Optical adjustment** | a play icon nudged 2 units to look centred | keep, document the reason | | **Missing step** | 20 used heavily by several teams | decide through the system's change process | The systemic classes matter most: fixing one cause, such as a type style or a card component, removes dozens of values at once. ## Fix in the right order 1. **Write a mapping** from every old value to its new step, agreed by design and engineering, so everyone makes the same call. 2. **Fix shared components first.** The restaurant card, the menu row and the order summary appear on many screens; correcting them corrects every screen that uses them. 3. **Fix type styles** whose line heights produce fractions. 4. **Then fix screens**, replacing raw numbers with spacing tokens so the value references a step rather than repeating a number. 5. **Review visually.** Moving 15 to 16 is invisible; moving 20 to 16 or 24 may change a layout's feel. Compare before and after screenshots rather than applying a blind global replace. ## Deciding on a missing step A value that many teams use independently is evidence, not just noise. Before adding it, ask: - Is it distinguishable from its neighbours? A 20 between 16 and 24 is borderline. - Would an existing step serve if the component's structure were fixed? - Does adding it bring back the problem the scale solved? Adding a step is a system change, reviewed and announced, not a quiet exception. ## Keep drift from returning - **Tokens everywhere.** Spacing in code references tokens; raw numbers become the exception that needs a comment. - **An automated check** in the build flags raw spacing values, so off-scale spacing is caught at review rather than months later. - **Design library presets.** Spacing presets and layout components in the design library make the scale the easiest choice for designers too. - **Layout primitives** in the component library apply stack and inline spacing, so product teams rarely set space by hand. - **A tracked metric.** The number of distinct spacing values, re-measured each quarter, shows whether the fix is holding. ## Communicating the change Teams need the mapping, the reasoning, and a heads-up about visual changes on their screens. Framing it as removing decisions they no longer need to make, rather than as policing, keeps the cleanup from feeling like a compliance exercise. The aim is not zero exceptions; it is that every exception left has a documented reason. ## What usually goes wrong - **Starting with screens.** Fixing screens before the shared card and row components means redoing the same fix in every screen, and the components reintroduce the old values next release. - **Skipping visual review.** A value moved from 20 to 16 can make a dense menu feel cramped; screenshots before and after catch it. - **Treating it as a one-off.** Without tokens and a check, the distinct-value count creeps back within a few releases, and the next audit finds the same problems.
- Twenty screens across three teams use 20 units, which is not on the scale; do you add a step?Treat it as evidence, not an order. Check whether 20 is visibly different from 16 and 24, whether a structural fix such as removing a component's outer spacing makes it unnecessary, and whether adding it reopens the choice problem. If it survives those questions, add it through the system's change process with an announcement, not as a quiet exception.
- Why do values like 13 and 17 often show up next to 1-unit borders?Someone measured the inset from outside the border and added the border's width to a 12 or 16 step. The fix is a rule for where the border sits: include it inside the component's inset so the outer size and the inner space both stay on the scale, and apply that rule in the component, not screen by screen.
- How do you prove the cleanup worked and is holding?Re-run the same inventory and track the number of distinct spacing values and the share of spacing that references tokens. Pair it with the automated check's count of flagged raw values per release. A falling count with few new flags shows the scale is now the default, not a one-time fix.
saying these in an interview costs you the question
- Replace every value with the nearest step in one global find-and-replace.
- Add a token for each of the 37 values so everything is on the system.
- Off-scale values are always mistakes; optical adjustments are never justified.
- Spacing drift is purely cosmetic, so a cleanup is never worth doing.
- Fix screens first, since that is where users see the problem.