Topic 2.3
Headings and the Document Outline
In one line
Headings h1 to h6 form the page's outline, a table of contents that screen-reader users navigate by; give each page one h1, nest levels by meaning, and don't skip levels.
Think of it like this
A textbook's table of contents. The book title is on the cover, chapters are numbered 1, 2, 3, and inside each chapter come sections 1.1, 1.2. You'd never find section 1.1.1 straight after Chapter 1 without a 1.1. HTML headings work the same way: h1 is the title, h2 the chapters, h3 the sections inside a chapter.
Words you'll meet
New words in this topic, in plain English. Come back here whenever one feels fuzzy.
- Heading
- A title for a part of the page, written with
h1(most important) toh6(least). - Heading level
- The number in the heading element. It says how deep the part sits in the outline.
- Document outline
- The tree of headings on a page, like a table of contents.
- Skipping a level
- Going from one heading to one more than a level deeper, like
h2straight toh4. - Rotor
- VoiceOver's menu that lists headings, links or landmarks so the user can jump to one.
- Outline algorithm
- An old, never-implemented HTML5 idea where sections reset heading levels. Removed from the standard in 2022.
Step by step
01Write the page title as h1
The h1 says what the whole page is about. One per page, near the top of main.
<h1>Making soft bread at home</h1>02Add the chapters as h2
Each major part of the page gets an h2. Think of them as the chapters in the table of contents.
<h1>Making soft bread at home</h1>
<h2>Ingredients</h2>
<h2>Method</h2>
<h2>Common problems</h2>03Nest sub-parts one level deeper
Inside "Common problems", each problem is a sub-part, so it gets an h3. When you return to a new major part, you go back up to h2.
<h1>Making soft bread at home</h1>
<h2>Ingredients</h2>
<h2>Method</h2>
<h2>Common problems</h2>
<h3>Dough doesn't rise</h3>
<h3>Bread is too dense</h3>
<h2>Next steps</h2>04Match headings to sections
When you use section and article, each one usually starts with a heading one level below its parent's. The heading level comes from the depth in the outline, not from the element it sits in.
<main>
<h1>Making soft bread at home</h1>
<section>
<h2>Common problems</h2>
<section>
<h3>Dough doesn't rise</h3>
</section>
</section>
</main>05Headings outside main
Sidebars and footers can have headings too: usually h2, because they're parts of the page alongside the main chapters. A screen-reader user pressing H meets them in source order.
06Fix size with CSS, not level
If the design wants the h3s small, keep them h3 and set their size in CSS. Level is meaning; size is looks.
h3 {
font-size: 1rem;
}Try it yourself
- 1
Fix the checker's complaints
In the second example, predict which two changes make the checker happy. Change the
h4s toh3s and the secondh1toh2, then run. OnlyChecked 5 headingsshould remain. - 2
Outline a real page
Copy the headings of a news article you like into the first example (keep their real levels from DevTools → Elements). Does its outline make sense on its own, without the body text?
- 3
Navigate by headings
If you have a screen reader (NVDA is free on Windows; VoiceOver is built into Mac with
Cmd+F5), open this page and pressH(NVDA) or open the rotor (VO+Uon Mac) to move through its headings.
Code & diagrams
This is roughly the list a screen reader's headings menu shows. Indentation is the level.
Preview
Console
Nothing logged yet.Expected console output
h1 Making soft bread at home
h2 Ingredients
h2 Method
h2 Common problems
h3 Dough doesn't rise
h3 Bread is too dense
h2 Next stepsFix the HTML until the checker only prints the last line.
Preview
Console
Nothing logged yet.Expected console output
Problem: found 2 h1 elements, expected 1
Problem: 'Basic' is h4 after h2
Checked 5 headingsBreak it on purpose
Errors are the best teachers. Make each change, read the error, guess what went wrong, then reveal the answer.
Break #1
Pick headings by size
Use <h4> for a section title because "h2 looks too big".
Break #2
Rely on sections to reset levels
Use <h1> as the heading of every <section>, trusting the old HTML5 outline algorithm.
Myth vs fact
Myth
A page must have exactly one h1 or it's invalid.
Fact
Several h1s are valid HTML. One h1 is the strong convention because it gives users and tools a clear page title.
Myth
Heading levels are for font sizes.
Fact
Levels are structure. Browsers give them default sizes, but you set the real look with CSS.
Myth
Inside a section you can start again at h1.
Fact
That relied on the outline algorithm, which nothing implemented and the standard removed in 2022. Use levels that match the real depth.
Pro corner
Extra depth for experienced readers. New to this? Skip it for now and come back later.
- ▸
Browsers' default stylesheets used to shrink an
h1nested insidearticle,aside,navorsection, a leftover from the outline algorithm. The HTML standard dropped those styles in 2025 and browsers are removing them, so always set yourh1size explicitly in CSS. - ▸
aria-levelcan override a heading's level for assistive technology (<div role="heading" aria-level="2">), but a realh2is always better. Web components and CMS-generated content are where you'll most often see this. - ▸
Headings feed tables of contents, search-result jump links and browser reader modes. Many CMSs build a sidebar table of contents from the
h2/h3outline, so a broken outline breaks those features too. - ▸
WCAG 2.2 success criterion 1.3.1 Info and Relationships requires that structure shown visually is also available in code; text that looks like a heading but is a styled
pfails it.
Remember this
- 1
The document outline is the tree of headings on a page: each heading starts a part, and that part lasts until the next heading of the same or a higher level. An
h3after anh2is a sub-part of thath2; the nexth2ends both. The heading level (the number) is what builds the tree, not the font size. - 2
Use **one
h1per page** for the page's main topic: usually the same idea as the<title>, worded for people already on the page. The HTML standard allows severalh1s, but oneh1is the common, recommended practice: screen-reader users often press1to jump to the page's main heading, and expect one. - 3
Don't skip levels going down: after an
h2, the next deeper heading is anh3, not anh4. A skipped level makes users wonder whether they missed a section. Going up any number of levels is fine: anh4can be followed by anh2when a new chapter starts. - 4
Choose the level by meaning, never by size. If an
h3looks too big, change its size with CSS; don't swap it for anh5. And never use a heading for text that isn't a heading (a tagline, a big price): use apand style it. - 5
Screen-reader users navigate by headings more than by anything else. In NVDA and JAWS,
Hjumps to the next heading and1to6to the next heading of that level; VoiceOver has a rotor that lists all headings. A clean outline lets them skim your page the way sighted users skim with their eyes. - 6
History you'll still read about: older HTML5 tutorials describe an outline algorithm where every
sectionorarticleresets the levels, so you could useh1everywhere. No browser or screen reader ever implemented it, and it was removed from the HTML standard in 2022. Always use real levels (h1–h6) that match the nesting.
Explain it without notes
What is the document outline, and how is it built?
Why shouldn't you skip heading levels, and is going up several levels at once also a problem?
How do screen-reader users use headings?
What was the HTML5 outline algorithm, and why shouldn't you rely on it?
Practice
Write the headings for a recipe page: page title, then Ingredients, Method (with sub-steps Preparing and Baking) and Serving.
This outline is broken: h1 Shop, h3 Shoes, h3 Bags, h1 Contact. Fix it.
Trade-offs
- ↔
Strict heading levels sometimes clash with a design where a small-looking heading must be an
h2; the fix is always CSS, which costs a rule or two but keeps the structure honest. - ↔
Reusable components (a card with a heading) don't know their nesting depth; teams either pass the level as a prop or pick the most common level, accepting an occasional imperfect outline.
Done when you can
I give each page one
h1that says what the page is about.I nest headings by meaning and never skip a level going down.
I change heading sizes with CSS, not by changing the level.
I can explain how screen-reader users move through headings.
I know the HTML5 outline algorithm doesn't work and why.