Pick a ratio, then stop inventing sizes
Most products do not have a type system. They have sizes chosen under pressure: 13px because a table felt tight, 22px because a heading felt small, 15px because 16px looked too big on a phone.
The page shows the problem. Sizes that differ by 1px do not create hierarchy. They create noise. A jump from 16px to 48px with nothing in between forces every new screen to invent another size.
A type scale removes that guesswork. You choose a base and a ratio. Every other size is a step from the base. That is the method.
The only formula you need
size = base × ratio ^ step
Step 0 is body text. Positive steps are larger. Negative steps are smaller. Round to a whole pixel or a clean rem. The ratio is the idea. The rounding is the implementation.
From a 16px base and a 1.25 ratio (major third):
| Step | Size | Typical role |
|---|---|---|
| −2 | 10px | Fine print, badges |
| −1 | 13px | Captions, table meta |
| 0 | 16px | Body |
| +1 | 20px | Lead, larger body |
| +2 | 25px | H4 |
| +3 | 31px | H3 |
| +4 | 39px | H2 |
| +5 | 49px | H1 |
| +6 | 61px | Display |
You will not use every step. That is fine. Pick roles from the scale. Do not add 17px because a card title "needed something in between."
The ratio is about density
The musical names are just labels. Use them to talk about how much contrast you want between sizes.
| Ratio | Name | Feel | Use it when |
|---|---|---|---|
| 1.067 | Minor second | Almost flat | Dense data, logs, spreadsheets |
| 1.125 | Major second | Tight and calm | Dashboards, settings, admin tools |
| 1.200 | Minor third | Balanced | Most product UI |
| 1.250 | Major third | Clear steps | SaaS marketing, docs, standard apps |
| 1.333 | Perfect fourth | Editorial | Blogs, magazines, reading apps |
| 1.414 | Augmented fourth | Dramatic | Portfolios, campaign heroes |
| 1.500 | Perfect fifth | Very strong | One display pair, not a whole product |
| 1.618 | Golden ratio | Extreme | A landing hero. Rarely a full UI. |
A dashboard with 1.618 will make headings shout over the data. A marketing page with 1.125 will make headings too quiet. Match the ratio to the job.
If you are not sure, start at 1.25. It works on both a homepage and a settings screen.
Start from body text, not from the H1
The base is the size where your typeface is easy to read as body copy. For most UI sans-serifs that is 16px. For a small x-height face, try 17px or 18px. For a dense data tool, 14px can work if you accept the tradeoff.
Do not start from the hero. A 72px display size does not tell you if body text should be 15px or 16px. Set a real paragraph first — about 45 to 75 characters per line, line-height around 1.4 to 1.6 — then build the rest.
Line-height is separate unless you choose to tie it to the scale. A simple starting point:
- Body and long reading: 1.5
- UI labels and short strings: 1.3 to 1.4
- Display headings: 1.1 to 1.2
Store line-height next to the size in the token. Sizes alone are only half a system.
Name roles, not pixels
The day someone asks for "the 18px," the scale is already slipping.
Name steps by job:
displayh1h2h3h4bodybody-lgcaptionoverline
A card title is h3 or h4, not "whatever fits." A timestamp is caption. New components pick a role. If no role fits, that is a product question, not a type question.
This is the same move that turns one brand hex into a named scale: the number is the primitive, the name is what the product uses. It also keeps handoff clean. Engineers should get tokens that already exist, not a screenshot with six mystery sizes.
Responsive type should keep the same relationships
Do not change every size on its own at each breakpoint. The relationship is the design. If h2 is four steps above body on mobile, it should still be four steps above body on desktop, even if both numbers change.
Two patterns that work:
- Change the base, keep the ratio. 16px body on mobile, 18px body on a wide screen. Every step follows.
- Use a slightly larger ratio on big screens. 1.2 on mobile, 1.25 on desktop. Hierarchy opens up when there is space.
What does not work: 14 / 16 / 20 / 28 on mobile and 16 / 18 / 24 / 40 on desktop. That is two systems in one repo.
Rounding is fine. Drift is not.
16 × 1.25³ = 31.25. Ship 31px, or 2rem if the root is 16px. Do not ship 30px in one file because of a 4px grid and 32px in another file for the same reason. Pick one rounding rule and write it down.
A 4px grid is useful. It should not override the scale. If the scale says 31px, 31px is more honest than 32px plus "close enough."
A short test before you lock the scale
Build one screen using only tokens from the scale:
- A page title
- A section title
- A card title
- Body text
- A caption
- A button label
If you need an extra size to make that screen work, the ratio is wrong or a role is missing. Fix the scale. Do not add a one-off size and plan to clean it up later.
Generate the steps. Then stop adding more.
Choose a base. Choose a ratio that matches the product. Generate the steps. Assign roles. Stop.
The typescale tool makes the first part fast. The second part is the real work: saying no to new sizes.
Tools mentioned
Ratio-based type hierarchy.