Essentiel Mis à jour : 2026-06

Landmarks HTML5 et zones de page : navigation par régions et lien d'évitement

Les landmarks HTML (header, nav, main, footer, aside) permettent de naviguer directement entre les zones d'une page sans lire tout le contenu. Structure sémantique, aria-label sur les nav multiples, lien d'évitement, pièges fréquents.

Table des matières

Dans NVDA, la touche D saute au prochain landmark. R dans JAWS fait la même chose. VoiceOver propose un rotor où les landmarks sont listés comme des chapitres. Sur n’importe quelle page bien structurée, un utilisateur peut atteindre directement le contenu principal, la navigation ou le pied de page sans traverser tout ce qui précède.

Sur une page construite avec des <div>, cette liste de landmarks est vide. L’utilisateur doit parcourir la page élément par élément depuis le début.

Ce que les landmarks exposent

Chaque élément HTML sémantique expose automatiquement un rôle de landmark à l’arbre d’accessibilité. Aucun attribut supplémentaire n’est nécessaire pour les cas simples.

Élément HTMLRôle landmarkAnnoncé comme
<header> (enfant de <body>)banner”Bandeau”
<nav>navigation”Navigation”
<main>main”Principal”
<footer> (enfant de <body>)contentinfo”Informations sur le contenu”
<aside>complementary”Complémentaire”
<form role="search"> ou <search>search”Recherche”
<section aria-label="...">region”Région : [label]”

L’équivalent ARIA (role="banner", role="navigation", etc.) produit le même résultat mais sur un élément générique. Les éléments natifs sont à préférer : ils exposent le bon rôle sans configuration.

<!-- ✅ Landmarks natifs -->
<header>...</header>
<nav aria-label="Navigation principale">...</nav>
<main id="contenu-principal" tabindex="-1">...</main>
<aside aria-label="Articles récents">...</aside>
<footer>...</footer>

<!-- ❌ Divs sans sémantique : aucun landmark exposé -->
<div id="header">...</div>
<div id="nav">...</div>
<div id="content">...</div>
<div id="footer">...</div>
→ NVDA, page avec landmarks :
  D → "Bandeau"
  D → "Navigation : Navigation principale"
  D → "Principal"
  D → "Informations sur le contenu"

→ NVDA, page avec divs :
  (aucun landmark disponible)

Plusieurs <nav> : le problème des doublons

Un site typique a trois ou quatre éléments <nav> : navigation principale, fil d’Ariane, pagination, navigation du pied de page. Sans aria-label sur chacun, la liste des landmarks affiche quatre fois “Navigation” sans distinction.

<!-- ❌ Quatre nav identiques dans la liste des landmarks -->
<header>
  <nav><!-- principale --></nav>
</header>
<main>
  <nav><!-- fil d'Ariane --></nav>
  <nav><!-- pagination --></nav>
</main>
<footer>
  <nav><!-- footer --></nav>
</footer>
→ NVDA liste des landmarks :
  Navigation
  Navigation
  Navigation
  Navigation

Chaque <nav> doit avoir un aria-label distinct qui décrit son rôle :

<!-- ✅ Chaque nav identifié -->
<header>
  <nav aria-label="Navigation principale">...</nav>
</header>
<main>
  <nav aria-label="Fil d'Ariane">...</nav>
  <nav aria-label="Pagination">...</nav>
</main>
<footer>
  <nav aria-label="Navigation pied de page">...</nav>
</footer>
→ NVDA liste des landmarks :
  Navigation : Navigation principale
  Navigation : Fil d'Ariane
  Navigation : Pagination
  Navigation : Navigation pied de page

L’aria-label sur un <nav> peut aussi référencer un titre adjacent via aria-labelledby. Si la section de navigation a un titre visuellement masqué (classe .sr-only), cette méthode est propre et évite la duplication d’intitulé.

<nav aria-labelledby="titre-nav-footer">
  <h2 id="titre-nav-footer" class="sr-only">Navigation pied de page</h2>
  <ul>...</ul>
</nav>

L’aria-label posé sur un <div> à la place du <nav>

Une erreur fréquente dans les sites construits avec des frameworks : le aria-label est posé sur le <div> englobant la navigation au lieu d’être sur l’élément <nav>.

<!-- ❌ aria-label sur le div : ignoré -->
<div aria-label="Navigation principale">
  <nav>...</nav>
</div>

<!-- ✅ aria-label sur le <nav> -->
<nav aria-label="Navigation principale">
  ...
</nav>

Le rôle implicite d’un <div> est generic. Les éléments génériques ne peuvent pas être nommés par ARIA. JAWS, NVDA, VoiceOver iOS et TalkBack ignorent le label. VoiceOver macOS et Narrator le lisent de façon incohérente selon les versions. Le aria-label doit être posé sur l’élément sémantique, ou sur un <div role="navigation"> si le <nav> natif ne peut pas être utilisé.

Un <header> à l’intérieur d’un <article> ou d’une <section> n’expose pas le rôle banner. Il est interprété comme un en-tête de section, sans rôle landmark. Seul le <header> enfant direct de <body> est le bandeau de la page.

Même principe pour <footer> : le landmark contentinfo n’est actif que pour le <footer> enfant direct de <body>. Un <footer> dans un <article> est un pied d’article, pas un landmark de page.

<body>
  <header><!-- landmark "banner" ✅ --></header>

  <main>
    <article>
      <header><!-- PAS un landmark, juste en-tête d'article --></header>
      <footer><!-- PAS un landmark, juste pied d'article --></footer>
    </article>
  </main>

  <footer><!-- landmark "contentinfo" ✅ --></footer>
</body>

Le formulaire de recherche du site mérite son propre landmark. Deux syntaxes sont valides.

La première utilise role="search" sur le <form> :

<form role="search" aria-label="Recherche sur le site">
  <label for="q">Rechercher</label>
  <input type="search" id="q" name="q">
  <button type="submit">Lancer la recherche</button>
</form>

La seconde utilise l’élément <search> introduit en HTML 5.3, supporté dans les navigateurs modernes depuis 2023 :

<search aria-label="Recherche sur le site">
  <form>
    <label for="q">Rechercher</label>
    <input type="search" id="q" name="q">
    <button type="submit">Lancer la recherche</button>
  </form>
</search>

Sans role="search", le formulaire apparaît dans la liste des landmarks comme “Formulaire” (role="form") uniquement s’il a un aria-label ou aria-labelledby. Un formulaire sans label n’expose aucun landmark.

Le lien d’évitement est le premier élément focusable de la page. Il permet de sauter directement au contenu principal sans traverser la navigation.

Un utilisateur qui navigue au clavier sur un site avec un menu de 12 liens doit appuyer 12 fois sur Tab avant d’atteindre le premier mot du contenu : et ce, sur chaque page. Le lien d’évitement ramène ce coût à une seule action.

L’erreur la plus commune : display:none sur le skip link.

<!-- ❌ display:none retire le lien de l'ordre de tabulation -->
<a href="#main" style="display:none">Aller au contenu</a>

Un lien avec display:none ne reçoit jamais le focus. Le skip link est présent dans le HTML mais totalement inutile. La même erreur se produit avec visibility:hidden.

La technique correcte : le clip masking, qui masque visuellement l’élément sans le retirer du flux de tabulation.

<!-- Premier élément dans <body> -->
<a href="#contenu-principal" class="skip-link">
  Aller au contenu principal
</a>

<header>
  <nav aria-label="Navigation principale">...</nav>
</header>

<main id="contenu-principal" tabindex="-1">
  <h1>Titre de la page</h1>
  ...
</main>
.skip-link {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.skip-link:focus {
  position: fixed;
  top: 0;
  left: 0;
  width: auto;
  height: auto;
  padding: 0.75rem 1.5rem;
  margin: 0;
  overflow: visible;
  clip: auto;
  white-space: normal;
  background: #1a1a6e;
  color: #fff;
  font-weight: bold;
  z-index: 10000;
  outline: 3px solid #fff;
  outline-offset: 2px;
}

tabindex="-1" sur le <main> est indispensable. Sans lui, le scroll se déclenche mais le focus ne se déplace pas sur l’élément : l’utilisateur de lecteur d’écran active le lien et reprend sa lecture depuis l’endroit où il était, pas depuis le début du contenu.

Un skip link toujours visible est encore mieux : il aide aussi les utilisateurs voyants qui naviguent au clavier et ne connaissent pas le Tab comme option de navigation.

En audit RGAA

Trois critères sont liés :

Critère 9.2 : la structure du document est-elle cohérente ? Vérifier avec la liste des landmarks de NVDA (Insert + F7, onglet Éléments, filtre Landmarks). Chaque zone principale doit apparaître. Les nav multiples doivent avoir des labels distincts.

Critère 12.6 : les zones principales sont-elles identifiables et contournables ? La présence des landmarks satisfait généralement ce critère. Vérifier que le moteur de recherche a role="search" et que le lien d’évitement fonctionne.

Critère 12.7 : un lien d’évitement vers le contenu principal est-il présent et fonctionnel ? Tester au clavier : premier Tab sur la page, le skip link doit apparaître. Entrée : le focus doit se déplacer sur <main>. Tester sur toutes les pages, pas uniquement la page d’accueil.

Checklist

  • <header>, <nav>, <main>, <footer> utilisent les éléments HTML natifs
  • Un seul <main> par page
  • <header> et <footer> sont enfants directs de <body> pour être des landmarks
  • Chaque <nav> a un aria-label distinct si plusieurs <nav> coexistent
  • Le formulaire de recherche a role="search" ou est dans <search>
  • Le skip link est le premier élément focusable de la page
  • Le skip link est masqué par clip masking, pas par display:none
  • Le skip link est visible au focus avec des styles :focus explicites
  • La cible du skip link (<main>) a tabindex="-1"
  • Le skip link est présent sur toutes les pages du site

Erreurs fréquentes en audit

ErreurCritèreCorrection
Page entière en <div> sans landmarks9.2, 12.6Remplacer par les éléments sémantiques natifs
Plusieurs <nav> sans aria-label9.2Ajouter un aria-label distinct sur chaque <nav>
<header> ou <footer> dans un <article> compté comme landmark9.2Ces éléments ne sont landmarks qu’en enfant direct de <body>
aria-label posé sur le <div> autour du <nav>9.2Déplacer le aria-label sur l’élément <nav>
Formulaire de recherche sans role="search"9.2, 12.6Ajouter role="search" sur le <form>
Skip link avec display:none12.7Remplacer par clip masking
Skip link présent mais ancre cible absente ou incorrecte12.7Vérifier que id="contenu-principal" existe sur <main>
<main> sans tabindex="-1"12.7Le focus ne se déplace pas à l’activation du skip link
Skip link absent des pages intérieures12.7Le skip link doit être dans le template global, présent partout

La lettre de l'Atelier A11Y

Ressources pédagogiques, critères RGAA commentés et retours de terrain : une lettre mensuelle pour progresser sur l'accessibilité numérique, sans jargon.

  • Nouveaux articles et ressources pédagogiques
  • Critères RGAA décortiqués avec des exemples concrets
  • Bonnes pratiques et retours d'expérience terrain
S'abonner à la newsletter (s'ouvre dans un nouvel onglet)

Gratuit. Désabonnement possible à tout moment.