Hierarchy & scale
Making headings look clearly different, not slightly different
Four axes: **size**, **weight**, **style** (italics, caps), and **colour**. Change _one at a time_. Bold + large + caps + coloured is noise, not hierarchy.
## Modular scales
A **modular scale** is a series of font sizes derived by multiplying a base by a fixed ratio. Common ratios:
| Ratio | Name | 16px base |
| ----- | -------------- | ----------------- |
| 1.125 | Major second | 16 / 18 / 20 / 23 |
| 1.200 | Minor third | 16 / 19 / 23 / 28 |
| 1.250 | Major third | 16 / 20 / 25 / 31 |
| 1.333 | Perfect fourth | 16 / 21 / 28 / 38 |
| 1.500 | Perfect fifth | 16 / 24 / 36 / 54 |
Break the scale when:
1. **The typeface has a sweet spot.** If 18px reads better than 16 or 20, use 18.
2. **Optical adjustment.** Headings may need to be smaller than the math suggests.
Keep sizes _clearly different from each other_. 16 / 18 / 20 looks intentional. 16 / 17 / 18 looks like indecision.
## Size contrast
**Clearly different or exactly the same.** Never close.
Aim for at least a **20–25% size jump** between adjacent levels. Past a few levels, use weight, style, or colour instead of pushing size further.
## Weight contrast
For body, use 400–500 (Regular, Book, or Medium). Bold is for selective emphasis, not entire paragraphs.
**As headings grow, their weight should drop.** A 48px Bold headline overwhelms 18px body. The same 48px in Regular feels balanced.
> For a balanced page, the weight should decrease slightly, not increase, as the size increases., Robert Bringhurst
## Heading colour
A 48px headline in the same black as 16px body looks _darker_ because there's more ink per square centimetre. A tint like `#1a1a2e` or a darkened brand hue balances it. Don't match link colour.
Avoid pure black (`#000`) on white. A tinted near-black like `#18181b` clears WCAG AA contrast (4.5:1 for body, 3:1 for large text).
## Caps as subheads
Set short subheadings in **letterspaced uppercase** or **small caps** rather than larger text:
```css
.subhead {
text-transform: uppercase;
font-size: 0.75rem;
letter-spacing: 0.1em;
font-weight: 600;
}
```
Size _down_, not up. Uppercase at body size feels like shouting. Sized down 20–30% it reads as a label. Always add tracking (0.05–0.15 em).
## Heading levels
One `h1` per page. `h2` for major sections. `h3` if needed. If you reach for `h4`, the document is trying to be two documents.
Headings should be **descriptive and skimmable**. _Install on macOS, Linux, or Windows_ tells a reader what they'll find. _Getting started_ does not.
Use `text-transform: uppercase` in CSS rather than typing capitals in HTML.