Headings and landmarks: the map screen reader users rely on

A sighted user glances at a page and sees its shape. A screen reader user gets that shape from headings and landmarks. If they are wrong, the page has no map.

Why it matters

Source: WebAIM Screen Reader User Survey. Screen readers let you list every heading or landmark on a page and jump straight to one. That only works if the page uses real headings and landmarks, in a sensible order.

What you will learn

Before the session: make sure you can run a screen reader.

  • Windows: install NVDA (free).
  • macOS: VoiceOver is built in. Turn it on and off with Cmd+F5.

Then read the screen reader cheat sheet.

Headings

Headings are a table of contents built into the page. Screen readers announce them with their level (“heading level 2, Programme”) and let users jump from one to the next.

The rules

  1. Use real heading elements (<h1>–<h6>). Bold text or a big <div> looks like a heading but is not one.
  2. One <h1> for the topic of the page. Not the logo: it is the same on every page.
  3. Don’t skip levels going down. After an h2 comes an h3, not an h4. Going back up any number of levels is fine.
  4. Pick the level from the outline, not the font size. Change the look with CSS.
  5. Every heading has a section of content after it, and every heading has text. No empty “spacer” headings.
  6. Headings describe what follows. “Opening hours” beats “Info”.

Example outline

h1 Autumn Reading Festival 2026
  h2 About the festival
  h2 Programme
    h3 Saturday 14 November
    h3 Sunday 15 November
  h2 Getting here
  h2 Opening hours        (sidebar)
  h2 Related events       (sidebar)
  h2 Contact              (footer)

Landmarks

Landmarks are the big regions of the page. Screen readers list them and jump between them, so users can skip straight to the main content, the navigation or the search. Use the HTML element first; reach for ARIA roles only when there is no element.

HTML elements and the landmarks they create
HTMLLandmarkNotes
<header>bannerOnly when it is not inside article, aside, main, nav or section.
<nav>navigationFor major groups of links. More than one? Give each a label: aria-label="Main", "Breadcrumb", "Footer".
<main>mainExactly one per page. Point the skip link at it.
<aside>complementaryRelated content that makes sense on its own.
<footer>contentinfoSame rule as header.
<form role="search"> or <search>searchThe site or page search.
<section> / <form>region / formOnly when they have an accessible name (aria-labelledby or aria-label).

The rules

  1. All content lives inside a landmark. Anything outside is easy to miss.
  2. Same role twice? Label them differently. Two unlabeled “navigation” landmarks sound identical.
  3. Don’t put the word “navigation” in the label. The screen reader already says it: aria-label="Main", not "Main navigation".
  4. Keep it small. A handful of landmarks is a map; twenty is noise.

How to check heading levels in your own work

1. Use a screen reader’s list

2. Use the structure inspector from this workshop

Drag this link to your bookmarks bar, then click it on any page. It lists the headings and landmarks and flags skipped levels, empty headings, missing main, duplicate unlabeled landmarks and content outside landmarks.

Page structure

Some sites block outside scripts. If the bookmarklet does nothing, open DevTools, go to the Console and paste the contents of assets/inspector.js.

3. Use browser tools

Quick self-review: read only your headings, top to bottom. Do they make sense as a table of contents? Could you find the thing you came for?

Hands-on exercises

Both pages below look the same. One has broken structure, one is fixed. Start each exercise with your screen reader already running.