Lesson 07 / 22
Spacing Scale
Deriving spacing values instead of choosing them; comparing linear, geometric, and hybrid scales by step count, distinguishability, and grouping ratio.
Contents
The grid made the horizontal measure derivable: column boundaries are no longer chosen, they are computed. The grid’s own inputs, though, were still free. The grid margin was chosen as 24 pixels, the gutter was chosen as 24 pixels. The same freedom continues on the vertical axis: the space between records, the space above a section heading, a button’s padding.
The inventory pulled out in the Repetition and Consistency lesson swelled in exactly this gap: 31 distinct values across four properties, 13 of them spacing. This lesson ties those 13 values to a production rule and shows which criteria the rule is chosen by.
A Scale Is a Production Rule
A spacing scale is a finite, rule-governed set of spacing values that can be used in the interface. What the scale provides is not the list itself but the list being closed: a value that is not on the scale cannot be used.
This closure does two things. First, it lowers the number of decisions; the question for a given space becomes not “how many pixels” but “which step,” and the number of options stays below ten. Second, it makes the decision auditable: a value outside the scale is not a preference, it is a violation.
A scale has four criteria, and these criteria pull against each other:
- Step count. Few steps mean few decisions, but too few steps cannot provide the distinction that is needed.
- Distinguishability. The difference between two neighboring steps has to be above the just-noticeable-difference threshold; if it is not, the scale carries a redundant step.
- Grouping ratio. The criterion set in the Proximity and Grouping lesson required a group boundary to be at least twice the within-group spacing. The scale needs to include step pairs whose ratio is at least 2.
- Proximity to raw values. When the existing design is fitted to the scale, the shifts should stay small; large shifts make the scale transition expensive.
Computing Three Scale Families
The program below generates three scale families and evaluates them against the four criteria. The raw values are the 13 spacing values pulled out in the Repetition and Consistency lesson.
// 07-scale.mjs — comparison of linear, geometric, and hybrid spacing scales const BASE = 4; const TOP = 96; const DISTINGUISH_THRESHOLD = 2; // two steps below this difference cannot be distinguished function linear(base, step, top) { const o = []; for (let v = base; v <= top; v += step) o.push(v); return o; } function geometric(base, ratio, top) { const o = []; let v = base; while (v <= top) { o.push(Math.round(v)); v *= ratio; } return [...new Set(o)]; } // Catalog interface's raw spacing values (from the Repetition and Consistency lesson). const RAW = [4, 6, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48]; function nearest(value, scale) { return scale.reduce((a, b) => (Math.abs(b - value) < Math.abs(a - value) ? b : a)); } function evaluate(name, scale) { const ratios = []; let indistinguishable = 0; for (let i = 1; i < scale.length; i++) { ratios.push(scale[i] / scale[i - 1]); if (scale[i] - scale[i - 1] <= DISTINGUISH_THRESHOLD) indistinguishable++; } const shifts = RAW.map((h) => Math.abs(nearest(h, scale) - h)); const avgShift = shifts.reduce((t, k) => t + k, 0) / shifts.length; // For nested grouping, a consecutive step pair: ratio must be at least 2 (see Proximity and Grouping). const groupable = ratios.filter((o) => o >= 2).length; console.log(`${name}`); console.log(` steps: ${scale.join(", ")}`); console.log(` step count: ${scale.length}`); console.log( ` neighboring ratio range: ${Math.min(...ratios).toFixed(2)} - ${Math.max(...ratios).toFixed(2)}` ); console.log(` indistinguishable neighboring pairs (diff <= ${DISTINGUISH_THRESHOLD}px): ${indistinguishable}`); console.log(` neighboring pairs with ratio 2 or greater: ${groupable}`); console.log(` average shift of raw values: ${avgShift.toFixed(2)}px largest: ${Math.max(...shifts)}px`); console.log(""); } evaluate("linear, 4px steps", linear(BASE, 4, TOP)); evaluate("linear, 8px steps", linear(BASE, 8, TOP)); evaluate("geometric, ratio 2.0", geometric(BASE, 2, TOP)); evaluate("geometric, ratio 1.5", geometric(BASE, 1.5, TOP)); const HYBRID = [4, 8, 12, 16, 24, 32, 48, 64, 96]; evaluate("hybrid", HYBRID); // Grouping levels do not have to be neighboring steps; they are chosen from within the scale. const GROUPING = [4, 8, 24, 48]; console.log("are grouping levels chosen from within the hybrid scale"); for (const d of GROUPING) { console.log(` ${String(d).padStart(3)}px in scale: ${HYBRID.includes(d) ? "yes" : "NO"} (step ${HYBRID.indexOf(d) + 1})`); } console.log(" consecutive grouping level ratios:"); for (let i = 1; i < GROUPING.length; i++) { const o = GROUPING[i] / GROUPING[i - 1]; console.log(` ${GROUPING[i - 1]} -> ${GROUPING[i]} ratio ${o.toFixed(2)} ${o >= 2 ? "separates" : "UNCLEAR"}`); }
linear, 4px steps
steps: 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64, 68, 72, 76, 80, 84, 88, 92, 96
step count: 24
neighboring ratio range: 1.04 - 2.00
indistinguishable neighboring pairs (diff <= 2px): 0
neighboring pairs with ratio 2 or greater: 1
average shift of raw values: 0.46px largest: 2px
linear, 8px steps
steps: 4, 12, 20, 28, 36, 44, 52, 60, 68, 76, 84, 92
step count: 12
neighboring ratio range: 1.10 - 3.00
indistinguishable neighboring pairs (diff <= 2px): 0
neighboring pairs with ratio 2 or greater: 1
average shift of raw values: 2.31px largest: 4px
geometric, ratio 2.0
steps: 4, 8, 16, 32, 64
step count: 5
neighboring ratio range: 2.00 - 2.00
indistinguishable neighboring pairs (diff <= 2px): 0
neighboring pairs with ratio 2 or greater: 4
average shift of raw values: 3.85px largest: 16px
geometric, ratio 1.5
steps: 4, 6, 9, 14, 20, 30, 46, 68
step count: 8
neighboring ratio range: 1.43 - 1.56
indistinguishable neighboring pairs (diff <= 2px): 1
neighboring pairs with ratio 2 or greater: 0
average shift of raw values: 1.69px largest: 6px
hybrid
steps: 4, 8, 12, 16, 24, 32, 48, 64, 96
step count: 9
neighboring ratio range: 1.33 - 2.00
indistinguishable neighboring pairs (diff <= 2px): 0
neighboring pairs with ratio 2 or greater: 1
average shift of raw values: 1.69px largest: 8px
are grouping levels chosen from within the hybrid scale
4px in scale: yes (step 1)
8px in scale: yes (step 2)
24px in scale: yes (step 5)
48px in scale: yes (step 7)
consecutive grouping level ratios:
4 -> 8 ratio 2.00 separates
8 -> 24 ratio 3.00 separates
24 -> 48 ratio 2.00 separates
Every Scale Loses One Criterion
None of the four candidates satisfies all four criteria at once, and the losses land in different places.
The linear, 4-pixel-step scale stays closest to the raw values: average shift 0.46 pixels. But it has 24 steps. The inventory held 13 distinct spacing values; this scale allows 24, meaning it imposes no constraint at all. A scale’s job is not to offer options but to narrow them; a scale that allows more options than the raw state does not earn the name.
The linear, 8-pixel-step scale brings the step count down to 12, but because it starts from a base of 4, it never includes common values like 8, 16, or 24: its steps run 4, 12, 20, 28. Average shift rises to 2.31 pixels. Its loss is that the base does not match the step size.
The geometric scale at ratio 2.0 generates only five steps, and all the neighboring ratios are exactly 2 — ideal for grouping. Its cost is the gap in the upper range: after 16 it jumps straight to 32, then to 64. The average shift of raw values is 3.85, the largest shift 16 pixels. A 24-pixel spacing value has no counterpart on the scale.
The geometric scale at ratio 1.5 gives fine adjustment, but it has two flaws. Rounding produces unmemorable numbers like 9, 14, 30, and 46, and more importantly: the number of neighboring pairs with a ratio of 2 or more is zero. With this scale, a group boundary cannot be expressed with a neighboring step; grouping always requires skipping two steps.
The hybrid scale satisfies all four criteria at a middling level: 9 steps, no indistinguishable neighboring pairs, average shift 1.69 pixels. Its loss is that the largest shift is 8 pixels — this comes from the raw value of 40 landing on 32, and it is a visible change.
The selection criterion is this: a scale should be finest in the most-used range and coarsest in the least-used range. In interfaces, most spacing falls between 4 and 32 pixels; between 64 and 96, fine adjustment is not needed. The hybrid scale does exactly this: it advances in 4-pixel steps in the lower range and doubles in the upper range.
A Scale Does Two Jobs at Once
The last block of output confirms the scale’s second job. In the Proximity and Grouping lesson, the catalog screen’s four grouping levels were set at 4, 8, 24, and 48 pixels. All four of these values are inside the hybrid scale: steps 1, 2, 5, and 7. The ratios between them are 2, 3, and 2 — all three clear the grouping threshold.
The real lesson here is that grouping levels do not have to be neighboring steps. A scale does two different jobs: neighboring steps close together for fine adjustment, steps far apart from each other for grouping. A scale generated with a single fixed ratio can only do one of these jobs. A ratio of 2.0 gives grouping but not fine adjustment; a ratio of 1.5 gives fine adjustment but not grouping. The hybrid scale gives both, because grouping levels are chosen from among the steps.
This requires one more rule when using a scale: access to the scale is not left unrestricted. A designer can choose 12 pixels for a group boundary; it exists on the scale, but if the within-group spacing is 8 pixels, the ratio stays at 1.5. The scale does not block the wrong value, it blocks the wrong pair. This is why the audit does not look at scale membership but at the ratio of the pairs actually used.
Naming a Step by Its Role, Not Its Measure
The names given to scale steps are also a decision. If a step is named by its measure — “twenty-four-pixel spacing” — every name becomes wrong the moment the scale changes. If a step is named by its position — “the fifth step” — every number shifts the moment a step is inserted in between.
The usable route is to tie the name to the role, not the measure: within-group spacing, between-block spacing, between-section spacing. A role name defines, in one place, which step of the scale it corresponds to; when the scale changes, only that definition changes, and the rest of the interface stays the same. The system-level counterpart of this approach is the subject of the Design Systems course; the only rule needed here is that spacing decisions are referred to by role name.
Summary
- A spacing scale is a closed set of usable spacing values; its value comes not from the list but from the impossibility of stepping outside it.
- A scale is evaluated against four criteria: step count, the distinguishability of neighboring steps, the presence of ratios of 2 or more for grouping, and the shift incurred when fitting to raw values.
- The linear, 4-pixel-step scale imposes no constraint because it allows 24 values; a scale’s job is not to offer options but to narrow them.
- A scale generated with a single fixed ratio gives only one of fine adjustment and grouping: a ratio of 2.0 gives grouping, a ratio of 1.5 gives fine adjustment.
- The hybrid scale satisfies both jobs by advancing finely in the lower range and coarsely in the upper range; grouping levels are chosen from within the scale, not from neighboring steps.
- Scale membership alone is not enough; the audit looks at the ratio of the spacing pairs used, and steps are referred to by role, not by measure.
Next Step
The scale said which values spacing can take, not which step gets used where. In the catalog results list, whether a given record uses 8 pixels or 24 pixels directly determines how many records appear on one screen. The next lesson computes that trade-off: it derives the number of records per screen from row height, finds how many screens are needed to scan 200 results, and shows in which direction the density decision is made for which tasks.
To keep your progress and take notes, Log in
My notes
Log in to take notes.