Type Scale Generator

Build a modular type scale from a base size and a ratio, preview every step at its real size, and copy it out as CSS custom properties.

Enable JavaScript to change the scale; the CSS below is for the defaults.

Body text. 16px is the browser default and the smallest most people should be asked to read.

Smaller ratios suit dense interfaces; larger ones suit editorial pages with few sizes.

One is usually enough. Anything below about 12px is hard to read.

Unit

rem respects the reader's own font size setting. px ignores it.

What 1rem equals. Leave at 16 unless you have changed the html font size.

  • xs 0.64rem The quick brown fox
  • sm 0.8rem The quick brown fox
  • base 1rem The quick brown fox
  • md 1.25rem The quick brown fox
  • lg 1.563rem The quick brown fox
  • xl 1.953rem The quick brown fox
  • 2xl 2.441rem The quick brown fox
  • 3xl 3.052rem The quick brown fox
type-scale.css
:root {
	--font-size-xs: 0.64rem;
	--font-size-sm: 0.8rem;
	--font-size-base: 1rem;
	--font-size-md: 1.25rem;
	--font-size-lg: 1.563rem;
	--font-size-xl: 1.953rem;
	--font-size-2xl: 2.441rem;
	--font-size-3xl: 3.052rem;

	--line-height-xs: 1.55;
	--line-height-sm: 1.54;
	--line-height-base: 1.52;
	--line-height-md: 1.5;
	--line-height-lg: 1.48;
	--line-height-xl: 1.44;
	--line-height-2xl: 1.4;
	--line-height-3xl: 1.36;
}

Build a modular type scale from one base size and one ratio, see every step at its real size, and copy it out as CSS custom properties.

How to use

  1. Start at 16px for body text. It is the browser default, and it is the size the rest of the scale is measured against.
  2. Pick the ratio for the kind of page. 1.125 or 1.2 suits a dense interface with many sizes; 1.333 and above suits an editorial page with three or four.
  3. Take fewer steps than you think. Five sizes covers most sites; a scale with twelve sizes is a scale nobody follows.
  4. Use rem, not px. A reader who has set a larger default font size gets it with rem and is ignored with px.
  5. Check the preview at the top and bottom. A ratio that looks elegant in the middle often produces a smallest step nobody can read and a largest step that will not fit on a phone.

Example

A 1.25 scale from 16px, as custom properties:

:root {
	--font-size-xs: 0.64rem;
	--font-size-sm: 0.8rem;
	--font-size-base: 1rem;
	--font-size-md: 1.25rem;
	--font-size-lg: 1.563rem;
	--font-size-xl: 1.953rem;
	--font-size-2xl: 2.441rem;
	--font-size-3xl: 3.052rem;
}

Each step is the one before it multiplied by 1.25. That is the whole idea: sizes that are related by the same jump read as a system, and sizes picked one at a time do not.

Pitfalls

  • Big ratios grow fast. At 1.618, five steps above 16px is 111px, which is a poster rather than a heading.
  • The smallest step is where scales fail. 0.64rem is about 10px, which is below what most people can read comfortably and below what many accessibility reviews accept.
  • A scale is a starting point, not a rule. Real designs nudge individual sizes, and that is fine as long as the nudge is deliberate.
  • Line height should fall as size grows. Body text at 1.5 and a 48px heading at 1.5 leaves the heading looking loose and disconnected.
  • rem is relative to the root font size, not the parent. em compounds when nested, which is why a scale built in em drifts.
  • Setting html { font-size: 62.5% } to make 1rem equal 10px overrides the reader’s own setting in a way that looks convenient and is not.
  • Fluid type with clamp() replaces some of this, but it still needs a scale at each end of the range.
  • Different typefaces at the same size look different. A scale tuned for one face usually needs re-checking after a font change.

Compatibility

Custom properties are supported by every current browser, and rem has been universal since IE9. The scale is plain arithmetic, so it works with any CSS approach: custom properties, a Sass map, Tailwind’s theme, or theme.json in a WordPress block theme. The tool runs entirely in your browser.

Frequently asked questions

Which ratio should I choose?
1.2 or 1.25 for most interfaces. Larger ratios need fewer steps and more whitespace to work.
How many steps do I need?
Usually five to seven in total. Every extra size is another decision every future page has to make.
rem or px?
rem. It respects the reader’s own browser font size setting, which px silently ignores.
Should the line height change per size?
Yes. Large text wants a tighter line. The generated properties do this for you, and you can turn it off.
Can I use this with theme.json?
Yes. Put each step in settings.typography.fontSizes with the same names, and WordPress generates the presets.
Weekly drops

New tools, when there are new tools

One email when something worth using ships. No schedule to fill, so no filler.

Your address goes nowhere else, and one click unsubscribes.