Free guideEditorial review in progress; your agent sees whether each guide's current version is reviewed. What “reviewed” means

Skip link, landmark regions and heading outline for every page

The structural accessibility baseline: a visible-on-focus skip link to main, one banner/nav/main/contentinfo per page with labeled duplicates, all content inside landmarks, and a single h1 with a logical heading outline.

Discipline
Websites
Type
Pattern
Platforms
Website
Version
1.0.0 · 2026-09-23

Overview

What: the page skeleton that lets keyboard and screen-reader users orient and jump.

Why:

  • Keyboard users otherwise tab through the entire header on every page. WebAIM notes browsers still do not offer native landmark navigation to sighted keyboard users, so a skip link remains necessary.
  • Screen-reader users navigate by landmarks and headings; the APG recommends placing all perceivable content inside a landmark and labeling repeated landmark types.
  • A meaningful heading outline also helps sighted skimmers (layer-cake scanning) and gives search engines clear topic structure.

Use on every template — it is cheap and foundational.

Implementation

  1. Skeleton:
<body>
  <!-- cookie banner (if any) goes first, per GOV.UK -->
  <a class="skip-link" href="#main">Skip to main content</a>
  <header>…<nav aria-label="Main">…</nav></header>
  <main id="main" tabindex="-1">
    <h1>…</h1>
  </main>
  <footer>…<nav aria-label="Footer">…</nav></footer>
</body>
  1. Skip link CSS (hidden until focused — never display:none):
.skip-link{ position:absolute; left:1rem; top:-100px; padding:.75rem 1rem;
  background:var(--color-bg); color:var(--color-text); outline:2px solid var(--color-focus); z-index:100; }
.skip-link:focus{ top:1rem; }
  1. Landmarks: exactly one main; top-level header → banner, top-level footer → contentinfo. Label every duplicate type: nav aria-label="Main", "Footer", "Breadcrumb", "On this page". Use <section aria-labelledby> only for regions users would want to jump to (don't label every section).
  2. Headings: one h1 per page matching the page topic (and close to the <title>); h2 for major sections; don't skip levels for styling — style with classes instead.
  3. Everything in a landmark: stray banners, toasts and "back to top" links belong inside header, main or footer.
  4. SPA routing: on client-side navigation, move focus to #main or the new h1 and update document.title.

Verification

  • First Tab press on every page shows the skip link visibly; Enter moves focus into main (next Tab lands in main content).
  • axe/Lighthouse: no "region" (content outside landmarks), "landmark-one-main", or "page-has-heading-one" failures.
  • Screen reader landmark list shows Banner, Main navigation, Main, Footer (and labeled extras) with no unlabeled duplicates.
  • Heading list reads as a sensible outline; exactly one h1; no skipped levels.
  • Client-side route changes update title and move focus.

Sources:

Limitations

  • Skip links matter most on pages with long headers; on minimal headers they are still expected and cheap.
  • tabindex="-1" on main can show a focus outline on click in some browsers; suppress with main:focus:not(:focus-visible){outline:none}.
  • Over-labeling regions creates noise; landmark lists should be short.