A modular type scale is the simplest way to pick every font size in a design system at once. Rather than choosing H1, H2, H3 etc. by eye, you pick a single ratio, and every size is computed from the one below it by multiplying by that ratio. The result is a scale where every size is proportionally related to every other size, which is what makes a typographic system feel coherent instead of arbitrary.
This calculator generates a type scale from a base size and a ratio, shows each step at actual size, and emits a CSS custom-properties block you can paste straight into a stylesheet.
The formula
For a base size $b$ and ratio $r$, the size at step $n$ is:
Step 0 is the base itself. Step 1 is the base times the ratio, step 2 is the base times the ratio squared, and so on. Negative steps divide instead of multiplying — step $-1$ is $b / r$.
Example: a base-16 major-third scale
Plugging base 16 and ratio 1.25 (major third) into the formula gives:
- Step -2: $16 / 1.25^2 \approx 10.24$ px
- Step -1: $16 / 1.25 = 12.8$ px
- Step 0: $16$ px (base)
- Step 1: $16 \times 1.25 = 20$ px
- Step 2: $16 \times 1.25^2 = 25$ px
- Step 3: $\approx 31.25$ px
- Step 4: $\approx 39.06$ px
- Step 5: $\approx 48.83$ px
- Step 6: $\approx 61.04$ px
Map those onto the levels in your design system however you like. A common mapping is:
- Step 6 → H1
- Step 5 → H2
- Step 4 → H3
- Step 3 → H4
- Step 2 → H5
- Step 1 → H6
- Step 0 → body
- Step -1 → small
- Step -2 → caption
Every size is a computable multiple of the base. If you decide to scale up your whole system for a larger screen, you only change the base — every level scales automatically.
The named ratios
The calculator includes eight preset ratios, each borrowed from music theory:
- Minor second (1.067) — extremely subtle, hard to distinguish
- Major second (1.125) — gentle, good for info-dense UIs
- Minor third (1.2) — conservative, readable at many sizes
- Major third (1.25) — popular default; strong but not extreme
- Perfect fourth (1.333) — noticeable step, starting to feel bold
- Augmented fourth (1.414) — √2, used in A-series paper ratios
- Perfect fifth (1.5) — bold, suited to expressive editorial design
- Golden ratio (1.618) — dramatic, each step is a full proportional jump. If that’s specifically what you want, the golden ratio typography calculator uses a milder $\sqrt{\varphi}$ step by default, which is more practical at web sizes.
Smaller ratios produce denser scales with many usable sizes crowded close together. Larger ratios produce bolder scales where each step is visually distinct but you quickly run out of space between body text and a reasonable H1. Pick one and commit — mixing ratios mid-scale defeats the point of using a scale at all.
CSS output
The generated CSS uses custom properties named by step offset:
:root {
--fs--2: 0.64rem;
--fs--1: 0.8rem;
--fs-0: 1rem;
--fs-1: 1.25rem;
--fs-2: 1.5625rem;
--fs-3: 1.9531rem;
--fs-4: 2.4414rem;
/* ... */
}
Reference them in your component styles:
body { font-size: var(--fs-0); }
h1 { font-size: var(--fs-6); }
.caption { font-size: var(--fs--2); }
The toggle at the top of the CSS block lets you switch between rem and px output. Rem is almost always the right choice because it inherits from the user’s preferred root font size; px is useful in environments where root inheritance is unreliable (older email clients, for example).
Why this beats picking sizes by eye
Designing a type system by eye is hard because your judgement of size is relative to the sizes next to it. A font size that looks “big enough for a heading” when you compare it to body text can look “way too big” when placed next to an even larger headline. Modular scales sidestep the problem: every step is mechanically proportional to the one below it, so you never have to make the judgement at all. You just pick a base, pick a ratio, and use whatever steps the math gives you.
The trade-off is that you lose the ability to say “this heading is exactly 42 px because I wanted it to be.” A modular scale is a constraint, and constraints have costs — but for a design system that has to work across many screens and many content types, consistency is usually worth more than one-off flexibility.
What this tool does not do
It does not let you snap the generated sizes to a pixel grid (which is occasionally useful when you want every size to be an even number). It does not handle fluid type scales that change with viewport width using clamp() — that is a different tool requiring min/max sizes and scaling behavior. And it does not set line-heights alongside the sizes — pair the output with the line height calculator for the leading that matches each size.