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.
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
AT announces:
waiting for landmark key press...
Legend
headerrole: bannernavrole: navigation| aria-label="Main"mainrole: mainasiderole: complementaryfooterrole: contentinfo
Multiple navs: unlabelled vs labelled
No aria-label
<nav>...</nav> <nav>...</nav>
AT landmark list:
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:
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.
Remember this
<section>withoutaria-labeloraria-labelledbyhasrole="generic"and is not a landmark.- Multiple
<nav>elements must each have a distinctaria-labelso 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 matchingid.
Done with this concept?
Mark it complete to track your progress. No login needed.