Guide · 10 min read

Modular scale: two numbers instead of twenty decisions

Every hand-picked font size is a decision nobody documented, and decisions that aren't documented drift. A modular scale replaces them with a base, a ratio, and a rule — then gets out of your way.

Where the idea comes from

Modular scales in typography borrow directly from music. Just as an octave is a 2:1 frequency ratio and a perfect fifth is 3:2, a typographic scale steps up by a fixed ratio: 4:3 (perfect fourth, 1.333), 3:2 (perfect fifth, 1.5), and so on. Renaissance printers used these proportions to set type that felt related across sizes; the practice was revived on the web because it solves the same problem — making twelve sizes look like they belong to one family.

The formula is the whole system:

size = base × ratiostep

Generate yours with the type scale calculator — pick a base and a ratio, and every step follows.

Choosing the base

The base is your body copy, and it is the one number that should not be negotiable per-page.

Express the base in absolute terms once, then work in rem everywhere else so that users who raise their browser default get a proportional result rather than a broken layout.

Ratio: the personality dial

RatioNameFeels like
1.067Minor secondFlat, dense, technical
1.125Major secondCompact, app-like
1.200Minor thirdBalanced, common default
1.250Major thirdClear hierarchy, safe
1.333Perfect fourthConfident, editorial
1.500Perfect fifthDramatic
1.618Golden ratioDisplay only, in practice

The honest summary: most products land between 1.2 and 1.333. Below that, headings stop reading as headings; above it, the top of the scale runs away from you on anything but a marketing page.

Use fewer steps than you think

Generate eight steps, ship five or six. Every additional near-identical size is an invitation for two authors to choose differently, and that divergence is precisely what the scale existed to prevent.

Line height is not part of the scale

A scale gives you sizes. Spacing is a separate decision, and it should move in the opposite direction: as type gets larger, line height gets tighter.

Measure: the constraint people forget

Line length and type size are coupled. The classical guidance — 45 to 75 characters per line, with around 66 often cited as the sweet spot — is about eye travel: too short and the eye resets constantly, too long and it loses the start of the next line.

This is why simply enlarging body text can make a page harder to read. If you raise the base from 16px to 18px inside a fixed-width column, your measure drops and the rhythm changes. Either widen the column, or accept the shift deliberately.

Making it fluid

A fixed scale is awkward across a 360px phone and a 1600px monitor. The modern answer is clamp(), which interpolates between a minimum and maximum using a preferred value tied to viewport width:

font-size: clamp(1rem, 0.875rem + 0.6vw, 1.25rem);

Three rules keep fluid type from becoming chaotic:

  1. Only fluidify the top of the scale. Body copy should usually stay fixed — users came for readable text, not for text that grows when they resize. Let headings and display sizes breathe.
  2. Derive the min and max from the same scale. Compute your scale at a small base and a large base, then clamp between the two corresponding steps. Otherwise your ratio quietly changes with viewport width, which is the whole thing you were trying to avoid.
  3. Always include a rem component in the preferred value. A preferred value expressed purely in vw breaks browser zoom for users who need it.

A practical implementation

Define the scale once as custom properties, and let components reference tokens rather than raw values:

:root {
  --scale-base: 1rem;
  --scale-ratio: 1.25;
  --step-1: calc(var(--scale-base) / var(--scale-ratio));
  --step-2: var(--scale-base);
  --step-3: calc(var(--scale-base) * var(--scale-ratio));
  --step-4: calc(var(--step-3) * var(--scale-ratio));
}

Now a brand refresh is two numbers instead of a search-and-replace across forty files. And because everything is expressed in rem, a user with a 20px browser default gets the entire system scaled up proportionally.

Mistakes worth avoiding


Scale maths: size = base × ratiostep. Guidance on measure reflects long-standing typographic practice rather than a formal specification; adapt it to your typeface, script and audience.