Sighted users skim a page in seconds: they spot the big headline, the menu and the main column. Screen reader users skim too, but they do it by jumping between headings and landmarks. That only works when the structure is in the HTML.
This lesson shows how screen reader users navigate, and how to build headings and landmarks that support them. The HTML Complete Course teaches the elements themselves.
How screen reader users skim
Screen readers offer shortcuts for moving through a page by element type. In NVDA on Windows, for example:
| Key | Moves to |
|---|---|
H / Shift+H | Next / previous heading |
1 to 6 | Next heading at that level |
D | Next landmark |
NVDA+F7 | A list of all headings, links or landmarks |
VoiceOver on macOS offers the same through the rotor (VO+U). Surveys of screen reader users by WebAIM have consistently found that navigating by headings is the most common way to find information on a long page.
A page with no headings forces the user to listen from the top. A page with good headings works like a table of contents.
Headings: 1.3.1 and 2.4.6
Two success criteria apply:
- 1.3.1 Info and Relationships (A): structure that is shown visually must also be available in code. Text that looks like a heading must be a real heading element.
- 2.4.6 Headings and Labels (AA): headings must describe the topic or purpose of their section.
<!-- Looks like a heading, but is not one -->
<p class="big-bold">Opening hours</p>
<!-- A real heading that screen readers can find -->
<h2>Opening hours</h2>
Build a logical outline
Treat headings as an outline of the page, not as font sizes.
<h1>Visit Northfield Library</h1>
<h2>Opening hours</h2>
<h2>Getting here</h2>
<h3>By bus</h3>
<h3>By car</h3>
<h2>Accessibility at the library</h2>
(The indentation is only for reading; it has no effect in HTML.)
Follow these rules:
- One
h1that describes the page, usually matching the main part of the page title. - Do not skip levels going down. An
h2is followed byh2orh3, noth4. Skipped levels make users wonder if they missed something. - Going back up is fine. After an
h3you can jump straight to anh2. - Choose the level by structure, then style with CSS. If a sub-section heading should look small, keep it an
h3and change its font size. - Do not use headings for text that is not a heading, such as a styled call to action.
Nesting section or article elements does not change heading levels in browsers or screen readers. The proposed "outline algorithm" was never implemented. Always choose h1 to h6 explicitly.
Check the outline
Use a browser extension such as HeadingsMap, or run this in the DevTools console:
document.querySelectorAll('h1, h2, h3, h4, h5, h6').forEach((h) => {
const level = Number(h.tagName[1]);
console.log(`${' '.repeat(level - 1)}${h.tagName}: ${h.textContent.trim()}`);
});
Read the result on its own. If it makes sense as a table of contents, your headings work.
Landmarks
Landmarks are the large regions of a page. Screen readers announce them and let users jump between them. HTML elements map to ARIA landmark roles automatically, so you rarely need ARIA here.
| HTML element | Landmark role | Notes |
|---|---|---|
header | banner | Only when it is not inside article, aside, main, nav or section |
nav | navigation | Major blocks of navigation links |
main | main | One visible main per page |
aside | complementary | Supporting content, such as related links |
footer | contentinfo | Same rule as header |
section | region | Only when it has an accessible name |
form | form | Only when it has an accessible name |
search | search | Wraps a search form |
A typical page skeleton looks like this:
<!DOCTYPE html>
<html lang="en-GB">
<head>
<meta charset="utf-8">
<title>Opening hours - Northfield Library</title>
</head>
<body>
<header>
<a href="/">Northfield Library</a>
<nav aria-label="Main">
<ul>
<li><a href="/books">Books</a></li>
<li><a href="/events">Events</a></li>
<li><a href="/visit" aria-current="page">Visit</a></li>
</ul>
</nav>
<search>
<form action="/search">
<label for="q">Search the catalogue</label>
<input id="q" name="q" type="search">
<button>Search</button>
</form>
</search>
</header>
<main>
<h1>Opening hours</h1>
<p>We are open every day except public holidays.</p>
</main>
<footer>
<nav aria-label="Footer">
<ul>
<li><a href="/privacy">Privacy</a></li>
<li><a href="/accessibility">Accessibility statement</a></li>
</ul>
</nav>
</footer>
</body>
</html>
Label landmarks of the same type
This page has two nav elements. Without labels, a screen reader lists "navigation, navigation". With aria-label, users hear "Main navigation" and "Footer navigation". Do not include the word "navigation" in the label, because the role is already announced.
Keep all content inside landmarks
Content outside any landmark is easy to miss when users jump between regions. Put everything inside header, nav, main, aside or footer.
Page title and language
Two small details make a big difference.
- 2.4.2 Page Titled (A): the
titleis the first thing a screen reader announces when a page loads, and it labels the browser tab. Put the specific part first: "Opening hours – Northfield Library", not "Northfield Library – Opening hours". - 3.1.1 Language of Page (A):
lang="en-GB"on thehtmlelement tells screen readers which voice and pronunciation rules to use. For a passage in another language, addlangto that element too, which 3.1.2 Language of Parts (AA) requires.
<p>The French say <span lang="fr">joie de vivre</span>.</p>
Summary
- Screen reader users skim by jumping between headings and landmarks.
- Use real heading elements in a logical outline: one
h1, no skipped levels going down. - Choose heading levels for structure and style them with CSS.
- Semantic elements create landmarks automatically; label repeated landmarks with
aria-label. - Put all content inside landmarks.
- Give every page a descriptive
titleand alangattribute.