Page Landmarks

A landmark is a labelled region of a page: the header, the navigation, the main content, the footer. Sighted users find these regions by glancing at the layout. Screen reader users find them through a landmarks menu, a list the screen reader builds from your HTML, letting them jump straight to the part of the page they want.

Semantic elements create landmarks automatically

You don’t need any extra code to get landmarks, using the right semantic element is enough. Each one maps to a landmark role:

ElementLandmark role
<header> (top-level, not inside article/section)banner
<nav>navigation
<main>main
<aside>complementary
<footer> (top-level)contentinfo
<form> with an accessible nameform
<header>...</header>
<nav>...</nav>
<main>...</main>
<aside>...</aside>
<footer>...</footer>

This is the biggest practical reason to use semantic HTML instead of <div> for page structure. A <div class="nav"> gives a screen reader nothing, it’s just an anonymous box. A <nav> shows up in the landmarks list automatically, with zero extra markup.

Naming multiple landmarks of the same type

If a page has more than one <nav>, for example a main menu and a footer menu, give each one an aria-label so they’re distinguishable in the landmarks list.

<nav aria-label="Main">
  <a href="/">Home</a>
  <a href="/blog">Blog</a>
</nav>

<footer>
  <nav aria-label="Footer">
    <a href="/privacy">Privacy</a>
    <a href="/terms">Terms</a>
  </nav>
</footer>

Without the label, a screen reader would just announce “navigation” twice with no way to tell them apart.

A skip link is a link at the very top of the page that jumps straight to <main>, letting keyboard users bypass repeated navigation on every single page instead of tabbing through it every time.

<body>
  <a href="#main-content" class="skip-link">Skip to main content</a>

  <header>...</header>

  <main id="main-content">
    ...
  </main>
</body>
.skip-link {
  position: absolute;
  top: -40px;
  left: 0;
  background: #000;
  color: #fff;
  padding: 8px 16px;
  z-index: 100;
}

.skip-link:focus {
  top: 0;
}

The link is positioned off-screen by default and only becomes visible when it receives keyboard focus, which is exactly the moment a keyboard user needs it. Don’t use display: none to hide it, that removes it from the keyboard tab order entirely, and defeats the purpose.

Common mistakes

  • Wrapping the whole page in <div>s and never using a real <nav>, <main>, or <footer>.
  • Multiple <nav> elements with no aria-label to tell them apart.
  • Hiding a skip link with display: none instead of positioning it off-screen until focused.

FAQ

Do I need a skip link on every page?

If your header/navigation is long or repeated across many pages, yes, it’s a small addition that meaningfully helps keyboard users. For a very short page it matters less, but it rarely hurts to include.

Can I check my landmarks without a screen reader?

Yes. Most browser dev tools have an accessibility tree inspector that lists landmarks, and browser extensions like axe DevTools or WAVE will flag missing or duplicate landmarks.

  • Semantic HTML : the elements that create these landmarks
  • ARIA Basics : naming and labelling elements when semantic HTML isn’t enough on its own