Landmarks ARIA : balises natives, régions et critère 9.2
Le contrat RGAA des points de repère : ce que le test 9.2.1 exige vraiment, les conditions sous lesquelles une balise est (ou non) un landmark, et le lien d'évitement du critère 12.7.
Les points de repère (landmarks) sont les rôles ARIA qui identifient les grandes zones d'une page (en-tête, navigation, contenu principal, pied de page) et permettent aux utilisateurs de technologies d'assistance d'en comprendre et d'en parcourir la structure. Les éléments HTML natifs sont à préférer systématiquement : <header>, <nav>, <main>, <aside>, <footer>, <form> et <section> portent déjà les rôles correspondants. Cette fiche est le contrat de référence côté RGAA : quelles zones sont exigées, sous quelles conditions une balise crée réellement un landmark, et où le lien d'évitement entre en jeu. Pour le tour d'horizon rôle par rôle : Rôles ARIA Landmark : Guide complet pour Structurer vos Pages.
Quand ce motif est le mauvais choix
Les points de repère servent à sauter directement vers une zone : si tout devient un landmark, la liste des points de repère redevient la page entière et ne sert plus à rien. Douze régions dans le rotor du lecteur d'écran, ce n'est plus de la navigation, c'est la page une deuxième fois. Trois cas où le landmark n'existe pas malgré les apparences :
- une
<section>sans nom accessible n'est pas un landmark : pour les technologies d'assistance, elle équivaut à un<div>avec des lettres en plus ; - un
<header>ou un<footer>imbriqué dans<article>,<aside>,<main>,<nav>ou<section>perd son rôlebanner/contentinfo: c'est un simple en-tête d'article, et c'est le comportement correct ; - un
<form>sans nom accessible ne crée pas de landmarkform.
Critères RGAA applicables
- Critère 9.2 : structure du document cohérente. Le test 9.2.1 exige que la zone d'en-tête soit structurée via
<header>, les zones de navigation principales et secondaires via<nav>(balise réservée à cet usage), la zone de contenu principal via une balise<main>visible unique, et le pied de page via<footer>. Point souvent mal connu : le critère 9.2 n'exige aucun landmarksearchnirole="search". - Critère 12.6 : zones de regroupement atteignables ou évitables. L'en-tête, la navigation principale, le contenu principal, le pied de page et le moteur de recherche doivent pouvoir être atteints ou évités. Un rôle landmark correspondant à la nature de la zone est l'un des mécanismes acceptés, au même titre qu'un titre de zone ou un lien d'évitement. C'est ici, et non au critère 9.2, que
role="search"sur la zone de recherche trouve sa place comme solution possible. - Critère 12.7 : lien d'évitement ou d'accès rapide. Un lien vers la zone de contenu principal est requis, et il a besoin d'un
<main>unique comme cible. Le glossaire RGAA précise que les liens d'évitement restent à privilégier par rapport aux seuls landmarks : sans lecteur d'écran, les navigateurs n'offrent aucune navigation par landmark.
Bonne pratique complémentaire, tirée du glossaire RGAA (entrée « Landmarks ») : quand plusieurs zones navigation coexistent, les différencier avec aria-label ou aria-labelledby ; les rôles banner, main et contentinfo restent uniques dans la page.
Interaction clavier attendue
Les points de repère n'ont aucune interaction clavier propre : ce sont des repères de structure, pas des widgets. Les lecteurs d'écran les exposent dans un menu dédié, et pour l'utilisateur clavier sans lecteur d'écran, le mécanisme d'accès rapide reste le lien d'évitement.
| Touche | Action |
|---|---|
| Tab (première tabulation de la page) | Fait apparaître le lien d'évitement, premier élément focalisable |
| Entrée (sur le lien d'évitement) | Déplace le focus dans la zone <main id="contenu"> |
| D (NVDA) | Point de repère suivant |
| Ctrl + Option + U (VoiceOver) | Ouvre le rotor, dont la liste des points de repère |
Pour que le lien d'évitement fonctionne réellement, sa cible doit porter tabindex="-1" : sans cela, certains navigateurs défilent mais laissent le focus en haut de page, et le Tab suivant retombe dans la navigation que l'utilisateur voulait justement éviter.
Rôles et attributs ARIA
| Élément | Rôle implicite | Condition |
|---|---|---|
<header> | banner | seulement hors de <article>, <aside>, <main>, <nav>, <section> |
<nav> | navigation | à nommer s'il y en a plusieurs |
<main> | main | une seule balise visible par page |
<aside> | complementary | |
<footer> | contentinfo | seulement au niveau supérieur |
<form> | form | seulement avec un nom accessible |
<section> | region | seulement avec un nom accessible |
<form role="search"> | search | zone de moteur de recherche |
<body>
<!-- Lien d'évitement : premier élément focalisable de la page. -->
<a href="#contenu" class="lien-evitement">Aller au contenu principal</a>
<!-- Niveau supérieur : rôle banner. -->
<header>
<!-- Nommée, car la page contient plusieurs <nav>. « Principale », pas
« Navigation principale » : le rôle est déjà annoncé par le lecteur d'écran. -->
<nav aria-label="Principale">
<ul>
<li><a href="/" aria-current="page">Accueil</a></li>
<li><a href="/projets">Projets</a></li>
</ul>
</nav>
<form role="search" action="/recherche">
<label for="q">Rechercher sur le site</label>
<input type="search" id="q" name="q">
<button type="submit">Rechercher</button>
</form>
</header>
<!-- Cible du lien d'évitement : tabindex="-1" pour que le focus s'y pose
réellement, et pas seulement le défilement. -->
<main id="contenu" tabindex="-1">
<h1>Titre de la page</h1>
<!-- <section> nommée : landmark region. Sans nom, ce serait un simple div. -->
<section aria-labelledby="titre-vedette">
<h2 id="titre-vedette">À la une</h2>
</section>
<article>
<!-- <header> imbriqué : PAS un banner, juste l'en-tête de l'article. Correct. -->
<header>
<h2>Titre de l'article</h2>
</header>
</article>
</main>
<!-- Niveau supérieur : rôle contentinfo. -->
<footer>
<nav aria-label="Pied de page">
<ul>
<li><a href="/confidentialite">Confidentialité</a></li>
</ul>
</nav>
</footer>
</body>
/* Le lien d'évitement doit être atteignable sans être intrusif : masqué hors
écran jusqu'à la prise de focus, puis visible. JAMAIS display: none, qui le
retirerait de l'ordre de tabulation : il ne pourrait plus jamais être atteint. */
.lien-evitement {
position: absolute;
inset-block-start: -100%;
inset-inline-start: 0;
z-index: 1000;
padding: 0.75rem 1rem;
background: #000;
color: #fff;
}
.lien-evitement:focus {
inset-block-start: 0;
}
À ne pas faire :
<!-- À ne pas faire : rôles redondants. <nav> EST role="navigation" :
du bruit qui masque les vrais problèmes en revue de code. -->
<nav role="navigation">…</nav>
<main role="main">…</main>
<!-- À ne pas faire : le rôle répété dans le libellé. Annoncé
« Navigation principale, navigation ». Dire simplement « Principale ». -->
<nav aria-label="Navigation principale">…</nav>
<!-- À ne pas faire : deux <nav> sans nom. Le rotor annonce
« navigation, navigation » : impossible de distinguer le menu du site
des liens légaux du pied de page. -->
<nav><ul>…</ul></nav>
<nav><ul>…</ul></nav>
Défauts fréquents et impact utilisateur
- Plusieurs
<main>visibles : structure invalide au regard du test 9.2.1 et cible ambiguë pour le lien d'évitement. - Deux
<nav>sans nom : la liste des points de repère annonce « navigation, navigation » ; l'utilisateur ne peut pas distinguer le menu du site des liens du pied de page. - Le rôle répété dans le libellé (
aria-label="Navigation principale") : annoncé « Navigation principale, navigation ». Le rôle est déjà là ; dire « Principale ». <section>sans nom accessible censée créer une région : aucun landmark n'est créé ; la zone n'apparaît jamais dans la liste des repères.- Sur-découpage en régions : une liste de repères plus longue que la page ne fait plus gagner de temps à personne.
- Lien d'évitement en
display: none: retiré de l'ordre de tabulation, il ne peut jamais recevoir le focus ; le lien existe et reste inatteignable. Le masquer hors écran et le rendre visible au focus. - Cible du lien d'évitement sans
tabindex="-1": le focus reste en haut de page et le Tab suivant retombe dans la navigation.
Ce que les outils automatiques ne détectent pas
Honnêteté d'abord : c'est l'un des rares motifs où les outils automatiques, le nôtre compris, couvrent une bonne partie du sujet. Plusieurs <main>, des landmarks du même type sans nom distinctif et du contenu hors de tout landmark se détectent très bien. Restent manuels :
- la qualité des libellés : un
aria-label="Navigation principale"redondant n'est signalé par aucun outil, alors qu'il dégrade chaque annonce ; - le sur-découpage : douze régions syntaxiquement valides et fonctionnellement inutiles ;
- le fonctionnement réel du lien d'évitement : visible à la prise de focus, et focus qui atterrit bien dans
<main>; cela ne se vérifie qu'au clavier ; - la pertinence du choix des zones, qui reste un jugement éditorial.
Vérifier ce composant
Protocole manuel, trois minutes :
- La liste des repères est le test : ouvrez le rotor du lecteur d'écran (VoiceOver : Ctrl + Option + U ; NVDA : touche D pour circuler). Vous devez voir une liste courte et lisible : banner, navigation « Principale », main, contentinfo. Si vous voyez « navigation, navigation, region, region », il manque des noms, ou il y a trop de régions.
- Le test du lien d'évitement : chargez la page, un seul appui sur Tab. Le lien doit apparaître. Entrée, puis Tab à nouveau : le focus doit être dans
<main>, pas de retour dans la navigation. S'il y retourne, la cible n'a pas detabindex="-1". - Le test du
<main>unique : dans la console,document.querySelectorAll('main').lengthdoit valoir 1.
Deux outils gratuits du site pour appuyer la vérification : le générateur de liens d'évitement produit un lien conforme (masquage hors écran, cible focalisable) prêt à intégrer ; le simulateur de lecteur d'écran affiche l'arbre d'accessibilité de votre page, où la liste des landmarks et leurs noms se lisent d'un coup d'œil.
Approfondir avec les fiches critères
Vérifier ce composant sur votre site ?
Le scan repère les défauts détectables automatiquement (rôles incohérents, champs sans étiquette, attributs ARIA orphelins) ; le reste se vérifie à la main avec les protocoles de cette fiche.
Lancer un scan gratuit