Structure a page with semantic landmarks

The problem

A page built from generic containers gives assistive technology no map: the reader cannot tell where navigation ends, what the primary content is, or how many regions exist, and every tool that lists landmarks produces an empty result.

Short answer

Use header, nav, main, and footer elements for the four top-level regions, keep exactly one main per page, and label any repeated landmark with aria-label.

The structure costs nothing to add and is the thing most often rebuilt later in ARIA.

Language: HTML
<body>
  <header>
    <a class="brand" href="/">DevExamples</a>
    <nav aria-label="Primary">
      <ul>
        <li><a href="/javascript/">JavaScript</a></li>
        <li><a href="/search/">Search</a></li>
      </ul>
    </nav>
  </header>

  <main id="main">
    <h1>Practical developer examples</h1>
    <p>Each example answers one task.</p>

    <section aria-labelledby="recent-heading">
      <h2 id="recent-heading">Recently published</h2>
      <ul>
        <li><a href="/javascript/debounce-a-scroll-handler/">Debounce a scroll handler</a></li>
      </ul>
    </section>
  </main>

  <footer>
    <nav aria-label="Footer">
      <ul>
        <li><a href="/about/">About</a></li>
      </ul>
    </nav>
  </footer>
</body>

Language: CSS
/* Landmarks carry meaning without changing the box model. */
header,
main,
footer {
  display: block;
}

main {
  max-inline-size: 68rem;
  margin-inline: auto;
  padding-block: 1.5rem;
}

Explanation

Five elements map to landmark roles automatically: header to banner, nav to navigation, main to main, footer to contentinfo, and aside to complementary, provided they are direct children of body and not nested inside an article or section. That implicit mapping is why a page of generic div containers produces an empty landmark list in a screen reader’s region navigator even when it looks identical, and why replacing those divs is usually a smaller change than hand-writing roles on them.

Exactly one main per page is the rule with consequences. It is the element a skip link targets, the region a reader jumps to when they want to stop hearing navigation, and the region a tool highlights as the page’s content. Two main elements make the jump ambiguous; none leaves the reader at the top of the document every time.

aria-label on repeated landmarks is not decoration. A page with a header navigation, a sidebar navigation, and a footer navigation produces three identical “navigation” entries, which is barely better than no structure at all. Naming them Primary, Related, and Footer turns the region list into a table of contents. Conversely, do not label a lone main — the role is already unique, and the labelled version is announced as “main, main content” in some combinations.

The section element with aria-labelledby is the third useful piece: a section with an accessible name becomes a region and appears in the same navigation list. A section with no name is a plain group, which is why the heading is referenced rather than left visually present only.

Assumptions

  • One top-level header, nav, main, and footer per document; a repeated header inside an article does not map to banner.
  • The id on main exists so a skip link can target it; see the related example.

Common mistakes

  • Writing role="banner" and role="main" on divs when the elements already provide them, which duplicates the mapping and drifts when the markup changes.
  • Wrapping the entire page in a section labelled as the main region, so the landmark list shows one enormous region.
  • Nesting header inside article and expecting a banner announcement.

Caveats

  • header and footer map to banner and contentinfo only at body level; inside an article they are generic, which is correct but often unexpected.
  • Landmarks do not replace a heading structure: readers navigate by both, and a page with perfect landmarks and missing headings is still hard to scan.

Follow-up

Related examples

Editorial links first, then deterministic same-task or same-topic candidates. Tags and shared language alone never qualify a candidate.

References