Episode 1 — Fundamentals / 1.5 — Semantic HTML and Browser Rendering
1.5.f — Headings Hierarchy (h1–h6)
In one sentence: Headings create an outline of your page — they are the fastest way for screen reader users to navigate and for search engines to understand topical structure, so skipping levels or using headings as styling hooks hurts both.
Navigation: ← 1.5.e — A11y & ARIA · 1.5.g — Lists →
1. What headings are for
- Navigation: screen readers expose a headings menu (rotor).
- Skimming: sighted users scan visually.
- Structure: nested sections map to h1 → h2 → h3 topics.
Headings are not font sizes — use CSS for appearance.
2. The outline model (simplified)
h1 Page topic (document title)
└─ h2 Major section
├─ h3 Subtopic
└─ h3 Subtopic
└─ h2 Major section
h1 count: in classic multi-page sites, one h1 per page representing the page topic is a simple, teachable rule. Single-page apps may reuse patterns per view — consistency matters more than debates; always avoid multiple unrelated h1 in the same view without reason.
3. Anti-patterns
| Anti-pattern | Why it hurts |
|---|---|
Skipping levels (h1 → h4) | Users lose mental model of depth |
Heading for visual line (“ALL CAPS SALE” as h3 for tiny banner) | Pollutes outline; feels like spam to SR users |
| Huge heading order for SEO | Looks manipulative; may not help; harms a11y |
Missing heading for a new <section> | section wants a heading per spec intent |
4. SEO + a11y alignment
Search engines use headings as weak-to-moderate structure signals alongside content, anchors, and external signals. Clear, descriptive headings (<h2>Shipping policy</h2>) help humans and machines.
4b. Components vs “one true document”
In design systems, each card might ship an <h3> title. That is fine if the page still exposes a coherent outline: the page supplies h1 (view topic) and major h2s; nested components use deeper levels consistently. Problems appear when every widget promotes itself to h2 without a parent section — the rotor becomes noisy.
4c. aria-labelledby with headings
When a <section> needs an accessible name, pair it with a visible heading:
<section aria-labelledby="reviews-heading">
<h2 id="reviews-heading">Reviews</h2>
…
</section>
This ties landmark naming to the same string sighted users read — better than a mystery aria-label.
5. Headings inside landmarks
Combine with 1.5.c:
<main>
<h1>Checkout</h1>
<section aria-labelledby="ship-heading">
<h2 id="ship-heading">Shipping address</h2>
…
</section>
</main>
6. Key takeaways
- Headings define an outline, not typography levels.
- Do not skip levels without a compelling reason.
h1should reflect the primary purpose of the view/page.- Pair sections with headings for coherent structure.
Explain-It Challenge
Explain without notes:
- Why using
<h4>purely because it “looks smaller in the browser default stylesheet” is the wrong reasoning. - What goes wrong for a screen reader user when every promo line is an
<h3>. - The difference between document title (
<title>) andh1.
Navigation: ← 1.5.e — A11y & ARIA · 1.5.g — Lists →