On each web page, is the document structure consistent (except in special cases)?

A screen reader user navigates a page like you search for an office in a building with no signs: without landmarks, they must explore everything from the entrance. The <header>, <nav>, <main> and <footer> tags are these signs. NVDA, JAWS and VoiceOver expose them as landmarks, direct jump points that users reach with a single keystroke without going through all preceding content.

Criterion 9.2 verifies that these four tags are present and placed in the right places. A <div class="header"> is not a <header>. Visually identical, semantically silent.

Concretely: the site header in a <header>, each main or secondary navigation area in a <nav>, the main content in a <main>, the footer in a <footer>. If multiple <main> elements coexist in the DOM (case of SPAs), only one must be visible: the others carry the hidden attribute.

Final rule: <nav> is reserved for main and secondary navigation areas. A filter block, a list of links to social networks or an isolated pagination do not justify its use. Each superfluous <nav> creates a phantom landmark that the user will need to identify, name and then ignore.

Un test to assess the semantic structure of the document

Landmarks <header>, <nav>, <main>, <footer>

Open the rendered DOM of the page (DevTools "Inspector" tab, not raw source code).

  1. Locate the site header area: it must use a <header> element, not a <div>.
  2. Locate each main or secondary navigation area: each must use a <nav> element.
  3. Verify that no <nav> is used for areas that are not navigation (filters, isolated pagination, secondary link lists).
  4. Locate the main content: it must use a <main> element.
  5. If multiple <main> elements are present in the DOM, verify that only one is visible and that the others have the hidden attribute.
  6. Locate the footer: it must use a <footer> element. ✅ Test validated if all these conditions are met for each area. ❌ Test failed as soon as an expected area uses a generic element instead of the required semantic tag.

Examples

❌ Non-compliant : Page structured with <div> only

<!DOCTYPE html>
<html lang="fr">
<head><title>Home</title></head>
<body>
  <div class="header">
    <div class="nav">
      <a href="/">Home</a>
      <a href="/services">Services</a>
      <a href="/contact">Contact</a>
    </div>
  </div>
  <div class="main-content">
    <h1>Welcome to our site</h1>
    <p>Main content of the page.</p>
  </div>
  <div class="footer">
    <p>&copy; 2026 Example Company</p>
  </div>
</body>
</html>

The areas are visually identifiable through CSS classes, but the DOM contains no landmarks. A NVDA user who presses the R key (landmarks) gets nothing. They must read the page linearly from the beginning to reach the main content.

✅ Compliant : Page structured with correct semantic tags

<!DOCTYPE html>
<html lang="fr">
<head><title>Home</title></head>
<body>
  <header>
    <nav aria-label="Main navigation">
      <a href="/">Home</a>
      <a href="/services">Services</a>
      <a href="/contact">Contact</a>
    </nav>
  </header>
  <main>
    <h1>Welcome to our site</h1>
    <p>Main content of the page.</p>
  </main>
  <footer>
    <p>&copy; 2026 Example Company</p>
  </footer>
</body>
</html>

The four semantic tags are in place. VoiceOver exposes a banner landmark for <header>, navigation for <nav>, main for <main> and contentinfo for <footer>. The user can jump directly to main content without traversing the menu.

Tips and pitfalls

⚠️ <nav> on everything that looks like a link list

This is the most common mistake in audits. Breadcrumb trail, links to social networks, article tags, pagination: everything ends up in a <nav>. However, test 9.2.1 requires that <nav> be reserved for main and secondary navigation areas. Each illegitimate <nav> is announced by screen readers as a navigation area: the user stops there, explores it and leaves empty-handed.

⚠️ JavaScript components render <div> by default

In React, Vue or Angular, encapsulating zones in components (<AppHeader>, <AppMain>) produces generic <div> by default. The visual result is identical, landmarks disappear. Always check the rendered DOM in the inspector, not the component source code. For Angular specifically: add a native <header> inside the component, or set role="banner" on the host element.

⚠️ Non-HTML5 doctype: criterion not applicable

If the page declares a doctype other than <!DOCTYPE html> — XHTML 1.0 Strict, HTML 4.01 Transitional, etc. — criterion 9.2 is not applicable. The <header>, <nav>, <main> and <footer> tags have no normative semantic value outside the HTML5 context. Check the doctype on the first line of the source before auditing.

⚠️ Multiple <main> in an SPA

Single-page applications sometimes load multiple views simultaneously in the DOM. If two <main> elements are visible at the same time, assistive technologies detect an inconsistency and may announce multiple main content areas. Only one <main> should be visible: the others carry the hidden attribute until the corresponding view is activated.

💡 Audit landmarks in 10 seconds with an extension

The Landmark Navigation extension (available on Firefox and Chrome) lists all landmarks detected on the page with a single click. If the list is empty or only shows the <body>, the criterion fails without needing to inspect the code. Under NVDA, the D key allows navigating from landmark to landmark: this is the fastest test and most representative of the actual experience.

Frequently asked questions

How do you replace <header>, <main> and <footer> with ARIA roles in RGAA?

Yes, when native tags are impossible to use (third-party components, technical constraints). role="banner" replaces <header>, role="main" replaces <main>, role="contentinfo" replaces <footer>, role="navigation" replaces <nav>. RGAA accepts this equivalence for criterion 9.2. That said, the native tag is still preferable: it works without JavaScript and reduces the risk of implementation error.

How many <nav> tags are allowed on a page according to RGAA?

There is no numerical limit, but each <nav> must correspond to a main or secondary navigation area. In practice: main menu, secondary menu (sub-navigation), breadcrumb trail if it constitutes true navigation. Beyond two or three <nav>, question the legitimacy of each. Each additional <nav> should carry an aria-label or aria-labelledby so that screen readers can distinguish them.

What RGAA rule applies to <header> and <footer> nested in an <article>?

None. Test 9.2.1 covers the global areas of the page: the site header, main navigation, main content and site footer. The <header> and <footer> nested in <article> or <section> are valid in HTML5 and can coexist without issue. They are neither required nor evaluated by this criterion.

How to quickly verify RGAA criterion 9.2 during an accessibility audit?

Two complementary methods. First: open DevTools, "Inspector" tab (not "Sources"), search for <header>, <nav>, <main>, <footer> in the rendered DOM. Second: use the Landmark Navigation extension or navigate with NVDA (D key). If no landmarks are exposed, the criterion fails immediately, regardless of the visual appearance of the page.

References