Page Landmarks

Landmark regions divide a page into named zones that screen reader users can jump between directly. Getting them right is not just about using the right element: it also means labelling identical landmark types so AT can tell them apart, and ensuring a skip link exists so keyboard users can bypass repeated navigation.

HTML6 min readConcept 32 of 42

What it is

A landmark is a named region of a page that a screen reader user can jump to from a landmark list, without having to read every element in between. The seven landmark roles and their native HTML elements are: banner (<header> at body level), navigation (<nav>), main (<main>), complementary (<aside>), contentinfo (<footer> at body level), search (<search> or <form role="search">), and region (<section> with an accessible name via aria-label or aria-labelledby).

The region landmark is the one most often misunderstood. A <section> without an accessible name has no landmark role: the browser assigns it role="generic". Only a named <section> becomes a region landmark. This means adding <section> without a label is no better than a <div> for AT landmark navigation.

Why it matters

Landmark navigation is the primary way screen reader users explore the structure of an unfamiliar page. NVDA users press D to cycle through landmarks. VoiceOver users open the rotor and select Landmarks. JAWS users press R. Each press moves the virtual cursor to the next landmark, announcing its type and label. A well-structured page might be navigable in five keystrokes: banner, navigation, main, region (articles), contentinfo. A div-soup page has no landmarks and the user starts reading from the top.

WCAG 2.4.1 (Bypass Blocks, Level A) requires a mechanism to skip repeated navigation. Landmarks satisfy this requirement because AT can jump past the banner and navigation directly to main. For keyboard users who do not use AT, a skip link serves the same function: a visually hidden <a href="#main-content">Skip to main content</a> as the first focusable element on the page.

How it works

Place exactly one <main> on each page. Place the <header> and <footer> as direct children of <body> (or at least not inside other landmarks) to get the banner and contentinfo roles. Use <nav> for all navigation blocks. Give every <nav> an aria-label if there are more than one: the label becomes the announced name before the role, so AT says "Main, navigation" and "Footer, navigation" instead of "navigation" twice.

For a skip link, add <a href="#main-content" class="skip-link">Skip to main content</a> as the very first child of <body>. Give the <main> element id="main-content". Style the skip link to be visually hidden by default but visible on :focus with a high-contrast appearance. Keyboard users who press Tab on page load will hit it first and can activate it to jump past the nav.

Use <section aria-label="Breaking news"> to create a named region landmark for a distinct thematic section within <main>. Keep the label short (two to four words). Do not add aria-label to every <section> mechanically: landmark proliferation makes the list unwieldy. Only name sections that a user would plausibly want to jump to directly.

Try it

Watch a screen reader walk through the page landmarks in order, hearing what gets announced at each stop.

Screen reader landmark walk

<header>
<nav aria-label="Main">
<main>
<aside>
<footer>

AT announces:

waiting for landmark key press...

Legend

  • headerrole: banner
  • navrole: navigation| aria-label="Main"
  • mainrole: main
  • asiderole: complementary
  • footerrole: contentinfo

Multiple navs: unlabelled vs labelled

No aria-label

<nav>...</nav>
<nav>...</nav>

AT landmark list:

navigation
navigation

Indistinguishable. User must enter each one to find out which is which.

With aria-label

<nav aria-label="Main">
  ...
</nav>
<nav aria-label="Breadcrumb">
  ...
</nav>

AT landmark list:

Main, navigation
Breadcrumb, navigation

Clear before entering. User jumps directly to the right one.

<section>: unnamed vs named

Unnamed section

<section>
  <h2>Latest news</h2>
  ...
</section>

Accessibility tree

role: regiongeneric

Not in the landmark list. AT must read through it sequentially.

Named section (region landmark)

<section aria-label="Latest news">
  <h2>Latest news</h2>
  ...
</section>

Accessibility tree

role: region | name: "Latest news"

Appears in landmark list as "Latest news, region". User can jump directly to it.

Check yourself

Pick an answer to lock it in, then read why. Getting one wrong is part of how it sticks.

  1. 1Does a <section> element without aria-label create a landmark region?
  2. 2A page has a primary nav and a breadcrumb nav, both using <nav> without aria-label. What does AT announce for each?
  3. 3A skip link points to href="#content". What must exist on the page for it to work?

Remember this

  • <section> without aria-label or aria-labelledby has role="generic" and is not a landmark.
  • Multiple <nav> elements must each have a distinct aria-label so AT users can tell them apart in the landmark list.
  • <main> is unique: exactly one per page; it satisfies the WCAG 2.4.1 bypass-blocks requirement.
  • A skip link (<a href="#main-content">) must be the first focusable element and its target must have a matching id.

Done with this concept?

Mark it complete to track your progress. No login needed.