The Typographic Scale Generator builds a harmonious set of font sizes from one base size and a musical ratio, then exports them as CSS custom properties or design-token JSON. Using a consistent ratio gives your headings and body text a deliberate, professional rhythm.
How it works
Each named step sits a fixed number of positions from the base. Its size is the base multiplied by the ratio raised to that distance — positive for larger steps, negative for smaller ones:
size(step) = base × ratio^(stepIndex − baseIndex)
rem = size / 16
steps = xs, sm, base, lg, xl, 2xl, 3xl, 4xl (base in the middle)
For example, with a 16px base and a major-third ratio of 1.25, the lg step is
16 × 1.25 = 20px and the xl step is 16 × 1.25² = 25px, while sm is
16 ÷ 1.25 = 12.8px.
Choosing the right ratio for your project
The ratio is the single most consequential setting. Here is a guide to common choices:
| Ratio | Name | Multiplier feel | Best for |
|---|---|---|---|
| 1.125 | Major second | Very subtle | Dense data UIs, dashboards |
| 1.2 | Minor third | Gentle | Editorial, long-form reading |
| 1.25 | Major third | Moderate | Most web apps |
| 1.333 | Perfect fourth | Noticeable | Marketing sites with clear hierarchy |
| 1.5 | Perfect fifth | Bold | Landing pages, hero-heavy layouts |
| 1.618 | Golden ratio | Dramatic | Single-product showcases |
A smaller ratio keeps headings closer to body text, which suits information-dense interfaces where you need many levels of hierarchy without large size jumps. A larger ratio creates dramatic contrast between heading levels, which is excellent on a marketing page that has only two or three text sizes in view at once.
Worked example
With a 16px base and the perfect fourth ratio (1.333):
xs→ 16 ÷ 1.333² ≈ 9px (0.563rem) — caption or badge textsm→ 16 ÷ 1.333 ≈ 12px (0.75rem) — small labelsbase→ 16px (1rem) — body copylg→ 16 × 1.333 ≈ 21px (1.333rem) — lead paragraph or large UI textxl→ 16 × 1.333² ≈ 28px (1.778rem) — section headings2xl→ 16 × 1.333³ ≈ 38px (2.369rem) — page headings3xl→ 16 × 1.333⁴ ≈ 51px (3.157rem) — hero display text
Using the output
CSS variables. Drop the exported :root block into your global stylesheet and reference sizes as var(--text-xl) anywhere in your CSS. Updating the scale later is a single change in one file.
JSON tokens. Feed the JSON output into a token pipeline — Tailwind’s theme.fontSize config, Style Dictionary, or a Figma token plugin — so the same values drive both design and code simultaneously.
Accessibility. Because all values are in rem, they scale with the user’s browser font preference. A user who has set their browser to 20px base will receive proportionally larger text throughout, which is a legal requirement under WCAG 2.1 for accessible text resizing.
Common mistakes
- Mixing absolute and relative units. If you define your scale in
rembut then set a parent element tofont-size: 14pxinpx, theremvalues recalculate from that element rather than the root. Keep your scale consistentlyrem-based and only adjust the root. - Using too many steps. Most UIs only actively use four or five of the eight steps. Choose the ones you need and leave the others as guardrails, rather than using all eight in the same design.