Building a Type Scale That Scales
Type is the interface. Every label, button, heading and error message is text, which means the type scale is not a decorative choice — it is the backbone of the whole design. A good scale gives you a small set of sizes that always fit together, so you stop inventing a new heading size every time a new screen appears.
Start with a base size and a ratio
A modular scale is the polite name for a geometric sequence: pick a base size, then multiply by a constant ratio to get each step up or down. The base for body text is almost always 16 pixels on the web, because that is the default and it comfortably fits around 60–75 characters per line at normal reading distances.
The ratio you choose sets the personality of the scale. Small ratios feel restrained and product-like; larger ratios feel editorial and dramatic.
| Ratio | Value | Feel | Good for |
|---|---|---|---|
| Minor second | 1.067 | Very subtle | Dense data tables |
| Major third | 1.250 | Balanced, calm | Most product UI |
| Perfect fourth | 1.333 | Clear contrast | Marketing and content sites |
| Perfect fifth | 1.500 | Dramatic | Editorial hero sections |
| Golden ratio | 1.618 | Extreme | Posters, rarely web UI |
For most interfaces a ratio between 1.200 and 1.333 hits the sweet spot. I default to 1.250 — a major third — because steps are clearly distinguishable without any single heading overwhelming the page.
Work the maths once, by hand
Begin at 16 and multiply. Round to whole pixels or sensible half-pixels, and stop when the numbers stop being useful.
- 12.8 → 13 (small / caption)
- 16 → 16 (base / body)
- 20 → 20 (large body / lead)
- 25 → 25 (h4 / card title)
- 31.3 → 31 (h3)
- 39.1 → 39 (h2)
- 48.8 → 49 (h1)
- 61 → 61 (display, sparingly)
That is eight sizes. You probably need six or seven. Delete anything you cannot name a clear use for — an unused step in a scale is just a temptation to use type inconsistently.
Naming beats remembering. Give each step a semantic name — caption, body, lead, title, display — rather than a size name like "18px". Then retheme the scale later without renaming anything.
Line height is a ratio, not a value
The most common type mistake is picking one line height for everything. Line height needs to be inversely proportional to font size: small text needs proportionally more leading, large text needs less, or headings look like they are floating apart.
- Small text (13–16px): 1.5 to 1.6 line height.
- Body (16–20px): around 1.5.
- Headings (25–49px): 1.15 to 1.3.
- Display (60px+): 1.0 to 1.1.
Notice the pattern: as size increases, the ratio falls. A 16-pixel paragraph at 1.05 line height is unreadable; a 60-pixel display headline at 1.6 looks broken. Tune both together.
Fluid scales without the guesswork
Static scales force a choice between a comfortable mobile size and a generous desktop size. Fluid type, built on viewport units and clamped, removes the choice by interpolating smoothly between a minimum and a maximum.
The mental model: every step has a mobile size, a desktop size and a viewport range over which it grows. Small text stays small; big text grows a lot. You can express this with a single clamp-style value per token, but even a two-versus-three breakpoint approach — mobile, tablet, desktop — captures most of the benefit without the complexity.
Watch the tails. Fluid type that grows on a huge monitor needs a maximum, or your 49-pixel heading becomes 90 pixels on an ultrawide and looks absurd.
Measure the line, not the page
Type readability lives at the line level. Aim for 45–75 characters per line for body text, with around 66 as the ideal for prose. Too wide and the eye loses its place on the return sweep; too narrow and the rhythm breaks into a jagged column.
Cap your text containers to fix this. At a 16-pixel font, a container of roughly 640 pixels yields around 70 characters. Set a maximum width on prose blocks and let the layout around them adapt. Do not let a full-width 1600-pixel container determine your line length.
Put accessibility in the scale from the start
Resist fixed pixel sizes alone, and never set body text below about 16 pixels on mobile where browsers allow zooming. Provide a scale that respects the user's own preference: use relative units so that a user who has set a larger default font size gets a proportionally larger interface rather than a broken one. And keep contrast at or above WCAG 4.5:1 for body text and 3:1 for large text (roughly 24px, or 19px bold).
Weight and tracking complete the job
Size is only one axis of hierarchy. Weight and letter-spacing give you finer control without adding steps to the scale:
- Weight: restrict yourself to two or three weights — a regular for body, a medium or semibold for emphasis and headings. More weights than that rarely read as distinct and inflate your font payload.
- Tracking (letter-spacing): large display text usually needs slightly negative tracking to look tight and deliberate; small text, especially all-caps labels, needs slightly positive tracking to stay legible. Body text sits at zero.
- Optical sizing: where a variable font offers it, letting the typeface adjust its own spacing by size removes the need to hand-tune display headings.
Combine the levers carefully. A heading that is large, bold and heavily tracked at once looks shouty; usually one strong lever plus one supporting lever is enough. And always set a maximum line length and a comfortable measure — weight cannot rescue a line that runs to 140 characters.
Ship it as tokens
Finally, encode the scale as design tokens so it travels from design into code intact. A token set is small, named and version-controlled:
- One token per step — size, line height and weight bundled as a unit.
- Semantic aliases — heading-1, body, caption — pointing at those steps.
- A documented rule for when to use each, so the scale is followed, not reinterpreted.
Get this right once and every future screen inherits typography that already works, which is exactly what a scale that scales is supposed to do.
Key takeaways
- Build the scale from a 16px base and a ratio — 1.200 to 1.333 suits most product interfaces.
- Keep six to eight named steps and delete any you cannot justify; unused steps invite inconsistency.
- Line height must fall as font size rises: about 1.5 for body, 1.15–1.3 for headings, near 1.0 for display.
- Use fluid, clamped sizing with a defined mobile minimum and desktop maximum for every step.
- Target 45–75 characters per line with a capped container width, and keep contrast at WCAG 4.5:1 for body text.
- Ship the scale as semantic design tokens so design and code stay in step.