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.
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.
- The quick brown fox
- The quick brown fox
- The quick brown fox
- The quick brown fox
- The quick brown fox
- The quick brown fox
- The quick brown fox
- The quick brown fox
- The quick brown fox
: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
- Start at 16px for body text. It is the browser default, and it is the size the rest of the scale is measured against.
- 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.
- Take fewer steps than you think. Five sizes covers most sites; a scale with twelve sizes is a scale nobody follows.
- Use rem, not px. A reader who has set a larger default font size gets it with rem and is ignored with px.
- 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?
How many steps do I need?
rem or px?
Should the line height change per size?
Can I use this with theme.json?
settings.typography.fontSizes with the same names, and WordPress generates the presets.