Headings and landmarks

Give the page an outline somebody can navigate without seeing it.

03of 16
≈ 12Min read
5Parts

How a screen reader user reads a page

Not from the top. They press a key to list the headings and jump to the interesting one; another to list the landmarks — banner, navigation, main, footer; another to list every link or every form control. A page with one heading and no landmarks offers none of that, and has to be read from the beginning every time.

This is the same skim a sighted reader does in half a second with their eyes. Structure is how you make it available to everyone else.

Headings are an outline, not a type scale

One h1, matching the page title. No skipped levels going down (h2 → h4 is a gap; h4 → h2 on the way back up is fine). If the size is wrong, change the CSS — the number is structure.

the level says where it sits, the CSS says how big it looks
<h1>The autumn catalogue</h1>        <!-- one per page: what this page is -->
  <h2>Pivot doors</h2>
    <h3>Vesper</h3>
    <h3>Arclith</h3>
  <h2>Flush doors</h2>

<!-- never skip a level to get a smaller font -->
<h1>…</h1>
<h4>…</h4>                            <!-- where did 2 and 3 go? -->
Your framework does not know the context

A "card title" component cannot know whether it is an h2 or an h3 on the page it lands on. Take the level as a prop, defaulting to something sensible, rather than hard-coding h3 and hoping.

Landmarks

<header> and <footer> are landmarks only at the top level — inside an <article> they are just that article's header. Two <nav>s on a page need distinguishing names: aria-label="Main" and aria-label="Breadcrumb", so the list of landmarks reads usefully rather than "navigation, navigation".

five elements, and the page becomes navigable
<header>   <!-- banner: the site header, once -->
  <nav aria-label="Main">…</nav>
</header>

<main id="main">   <!-- exactly one, and everything that is this page -->
  <h1>…</h1>
</main>

<aside aria-label="Related doors">…</aside>   <!-- complementary -->
<footer>…</footer>                            <!-- contentinfo, once -->

Without it, a keyboard user presses Tab through forty navigation links on every page to reach the content. It must be the first tabbable thing, and it must become visible when focused — a skip link you cannot see is a trap for a sighted keyboard user.

the first thing in the document, visible on focus
<a class="skip" href="#main">Skip to the content</a>

<style>
.skip { position: absolute; left: -9999px; }
.skip:focus { left: 8px; top: 8px; position: fixed; background: #fff; padding: 8px 12px; }
</style>

The page title, and the language

The <title> is read before anything else and is what a user sees in a list of twenty tabs: put the specific part first. lang decides pronunciation — an English voice reading Azerbaijani is unintelligible — and it must be updated on the element when a passage is in another language.

In a single-page application the title has to be updated on every route change, and so does focus — which is the Focus lesson.

the first thing announced, and the voice used to announce it
<html lang="az">
<title>Vesper — Qapılar — DOMVYBE</title>

Practice