Type scale generator

A fluid scale with the real cap-height, and line length checked.

Typeface
16 px
19 px
Ratio, wide

Every ratio here is free. Narrow screens use 1.2 so headings do not run off the edge.

5
2
62 % of viewport
Body line length
  • 360 → 29
  • 768 → 58
  • 1024 → 74
  • 1280 → 89
  • 1440 → 98

Over WCAG 1.4.8's 80-character ceiling at the wider end. Cap the column at 37.46rem (599px) to land on 66.

3xlMeasure what you set39.81→57.98px · cap 42.21 · x 31.66
2xlMeasure what you set33.18→46.39px · cap 33.77 · x 25.33
xlMeasure what you set27.65→37.11px · cap 27.02 · x 20.26
lgMeasure what you set23.04→29.69px · cap 21.61 · x 16.21
mdMeasure what you set19.2→23.75px · cap 17.29 · x 12.97
baseMeasure what you set16→19px · cap 13.83 · x 10.37
smMeasure what you set13.33→15.2px · cap 11.07 · x 8.3
xsMeasure what you set11.11→12.16px · cap 8.85 · x 6.64

With text-box-trim, so the box matches the letters.

:root {
  --step-3xl: clamp(2.4881rem, 2.1096rem + 1.6824vw, 3.6238rem);
  --step-2xl: clamp(2.0738rem, 1.7985rem + 1.2231vw, 2.8994rem);
  --step-xl: clamp(1.7281rem, 1.531rem + 0.8759vw, 2.3194rem);
  --step-lg: clamp(1.44rem, 1.3015rem + 0.6157vw, 1.8556rem);
  --step-md: clamp(1.2rem, 1.1052rem + 0.4213vw, 1.4844rem);
  --step-base: clamp(1rem, 0.9375rem + 0.2778vw, 1.1875rem);
  --step-sm: clamp(0.8331rem, 0.7942rem + 0.1731vw, 0.95rem);
  --step-xs: clamp(0.6944rem, 0.6725rem + 0.0972vw, 0.76rem);
}

/*
  text-box-trim removes the space above the cap-height and below the
  baseline, so a heading sits on its box instead of floating inside it.
  Baseline across all engines since Firefox 154 (Aug 2026); the older
  leading-trim name is not needed any more.
*/
h1, h2, h3, h4, .trim {
  text-box: trim-both cap alphabetic;
}

In short

Most type scale tools multiply a number by a ratio and hand you the list. That part is arithmetic. The harder question — whether the scale you just made is actually readable at the sizes and widths it will be used at — is left to you.

What type scale is

An ordered set of font sizes derived by multiplying a body size by a ratio. The arithmetic is the easy part; what decides whether a scale works is the cap-height it produces in the typeface you chose and the line length it produces in the column you have.

What this tool does that others do not

  • Every step reports its real cap-height and x-height

    font-size sets an invisible em box. What a reader perceives is the cap-height and the x-height, and those vary enormously between families — set the same 32px heading in two faces and one can look a full step smaller. Both measurements are given in pixels, from the font’s own metrics.

  • Line length checked at five viewports

    A column set to a percentage of the viewport sails past the readable ceiling on a wide screen without anything visibly breaking. The character count is computed from the font’s real average advance width, not the usual guess of half the font size.

    WCAG 1.4.8 puts the ceiling at 80 characters. Inter at 16px in a 62% column reaches about 117 characters at 1440px.

  • Two ratios, expressed as clamp()

    A ratio that looks confident on a desktop runs a heading off the edge of a phone. A flatter ratio at the narrow end and a fuller one at the wide end keeps the top of the scale usable on both, which is why each step is a clamp() rather than a fixed size. The endpoints are in rem so a reader’s own browser default still applies; only the fluid middle term uses viewport units.

  • text-box-trim in the output

    Every line carries empty space above the capitals and below the baseline, built into the font, and it is why a heading never lands quite where you positioned it. text-box-trim removes it so the box matches the letters. It is emitted with the scale rather than left as an exercise.

    text-box-trim reached Baseline across all browser engines in August 2026.

How to use it

  1. Set the body size and the typeface

    The cap-heights reported for every other step depend on the family, so choose it before reading any of the numbers.

  2. Choose two ratios, not one

    The narrow-end ratio governs phones and the wide-end ratio governs desktops. Every classical ratio is available here, including the golden ratio, which is 1.618 and not a premium feature.

  3. Watch the character counts as you move the scale

    They update across five viewports. Fix a count over 80 by capping the column, not by shrinking the text.

  4. Take the CSS with the trim included

    Copy the whole block. Removing text-box-trim later means re-tuning every vertical space that was set with it in place.

Worked example

Real input, real figures.

A measure that is too long with nothing visibly wrong

You give it

Inter at 16px, column width 62% of the viewport, viewport 1440px.

You get

About 117 characters per line, against the 80-character ceiling in WCAG 1.4.8 — roughly half as long again. Nothing on the page indicates the problem, which is why the count is shown per viewport rather than at one width.

Against a typical type scale generator

AspectThis toolA typical generator
Per-step outputfont-size plus real cap-height and x-heightfont-size
Line lengthCharacters per line at five viewportsNot addressed
Fluidityclamp() with two ratios and rem endpointsA fixed list, or one ratio
RatiosAll of them, freeGolden ratio behind a paid tier
Trimtext-box-trim emitted with the scaleNot mentioned

Guide

A font size is not a size

font-size sets the em box, which is invisible. What a reader perceives is the cap-height and the x-height, and those vary enormously between typefaces. Set the same 32px heading in two families and one can look a full step smaller. Every row here reports both measurements in pixels, taken from the font's own metrics.

Line length is part of the scale

A body size is only sensible in relation to the column it sits in. WCAG 1.4.8 puts the ceiling at 80 characters per line. A column set to a percentage of the viewport sails past that on a wide screen without anything visibly breaking — Inter at 16px in a 62% column reaches about 117 characters at 1440px, roughly half as long again as the limit.

So the line count is shown across five viewports as you change the scale, using the real average character width of the font rather than the usual guess of half the font size, which is wrong by a wide margin for condensed and monospaced faces.

The space you did not ask for

Text carries built-in space above the capitals and below the baseline. It is why a heading never lands exactly where you put it and why vertical rhythm is so fiddly to tune. The CSS output includes text-box-trim, which removes it, so the box matches the letters. It became Baseline across all engines in August 2026.

Questions people ask

Straight answers. Each one links directly: copy the address after opening it.

What makes this different from the other type scale generators?

Two things. It reports the cap-height and x-height in pixels for every step, not just the font-size — because font-size describes an invisible box and what you actually read is the letters inside it, which differ by up to 30% between families at the same nominal size. And it counts the characters per line your scale will produce across five viewports, against the 80-glyph ceiling in WCAG 1.4.8, rather than leaving line length as a separate problem.

Why is every ratio free here?

Because a ratio is a number. The best-known generator puts the golden ratio behind a paid tier, which is charging for 1.618. Every classical ratio is on this page, and so is the output in four formats.

What is text-box-trim, and why is it in the CSS?

Every line of text carries empty space above the capital letters and below the baseline, built into the font. That space is why a heading never quite sits where you positioned it. text-box-trim removes it, so the box matches the letters and your spacing becomes predictable. It reached Baseline across all engines in August 2026, so it is safe to ship — and it is emitted alongside the scale rather than left as an exercise.

Why does the scale use two ratios?

A ratio that looks confident on a desktop runs a heading off the edge of a phone. Using a flatter ratio at the narrow end and a fuller one at the wide end is what keeps the top of the scale usable on both, and it is the reason each step is a clamp() rather than a fixed size.

Why rem and not px?

A scale pinned in pixels ignores the reader who has set a larger default font size in their browser. The clamp endpoints are in rem so that setting still applies; only the fluid middle term uses viewport units.