Bac à sable
Le menu déroulant
Le piège que je relève en audit sur une barre de navigation est un role="menu", qui la fait passer pour le menu d'un logiciel. Avec l'attribut popover, ta liste se referme à Échap et au clic ailleurs, et le navigateur expose l'état déplié du bouton.
- Technique
- popover
- Navigateurs
- Chrome 125+, Firefox 147+, Safari 26+
- JavaScript
- Aucun
Démo
Anatomie
navLa navigation, nommée avecaria-label.button popovertargetLe bouton qui déplie la liste.ul popoverLa liste dépliée, au-dessus de la page et ancrée sous le bouton.aUn lien de la liste.
Code HTML
<nav aria-label="Navigation principale">
<ul>
<li>
<!-- Élément déclencheur : ouvre et ferme le sous-menu -->
<button type="button" popovertarget="account-menu">Mon compte</button>
<!-- Sous-menu : de simples liens dans un popover, sans rôle de menu -->
<ul id="account-menu" popover>
<li><a href="/compte/profil">Mon profil</a></li>
<li><a href="/compte/commandes">Mes commandes</a></li>
<li><a href="/compte/parametres">Paramètres</a></li>
<li><a href="/deconnexion">Se déconnecter</a></li>
</ul>
</li>
<li><a href="/aide">Aide</a></li>
</ul>
</nav>/* La liste s'ancre sous son bouton, au lieu du centre de l'écran.
Un nom d'ancre par bouton : avec un nom partagé,
toutes les listes s'ouvriraient sous le dernier bouton */
[popovertarget="account-menu"] {
anchor-name: --account-button;
}
#account-menu {
position-anchor: --account-button;
inset: auto;
top: anchor(bottom);
left: anchor(left);
margin: 6px 0 0;
}Usages
Recommandé pour
- Regrouper les pages d'une même rubrique dans la navigation principale.
- Une liste de liens courte, lisible d'un coup d'œil.
Déconseillé pour
role="menu"etrole="menuitem"sur une navigation de site. Ils promettent les flèches d'un menu d'application, comme Fichier ou Édition.- Une liste qui ne s'ouvre qu'au survol.
- Un lien « Mon compte » qui ouvre aussi la liste : un élément est un lien ou un bouton, jamais les 2.
Accessibilité
Rôles et attributs ARIA
Un seul attribut ARIA, aria-label sur la navigation. L'état du bouton vient de popovertarget, sans aria-expanded.
| Attribut | Élément | Description |
|---|---|---|
aria-label="Navigation principale" | nav | Nomme ce repère de navigation : le lecteur d'écran le distingue des autres navigations de la page. |
popovertarget="account-menu" | button | Relie le bouton à la liste id="account-menu". Le lecteur d'écran reçoit « Mon compte, réduit, bouton », puis « développé » à l'ouverture. |
popover | ul | Fermée, la liste sort de l'arbre d'accessibilité. Ouverte, le lecteur d'écran reçoit une liste ordinaire, placée juste après le bouton dans le code : elle se lit et se parcourt dans l'ordre. |
Navigation au clavier
| Touche | Action |
|---|---|
| Tab | Atteint le bouton Mon compte, puis les liens si la liste est ouverte |
| Entrée ou Espace | Ouvre ou ferme la liste |
| Échap | Ferme la liste. Si le focus était sur un lien, il revient au bouton |
| Tab après le dernier lien | Passe au lien Aide. La liste reste ouverte jusqu'à Échap ou au prochain clic ailleurs |
Ordre de tabulation
- Le bouton « Mon compte ».
- « Mon profil », si la liste est ouverte.
- « Mes commandes ».
- « Paramètres ».
- « Se déconnecter ».
- Le lien « Aide ». Liste fermée, Tab y arrive directement depuis le bouton.
Avec un lecteur d'écran
Exemple sur Chrome avec VoiceOver. Les mots changent d'un lecteur d'écran à l'autre.
| Action | Annonce |
|---|---|
| Tab sur le bouton | « Mon compte, réduit, bouton » |
| Entrée | « développé » |
| Tab | « lien, Mon profil » |
Critères RGAA concernés
- Critère 10.7 : Dans chaque page web, pour chaque élément recevant le focus, la prise de focus est-elle visible ?
- Le focus reste visible sur le bouton et sur chaque lien.
- Critère 12.8 : Dans chaque page web, l’ordre de tabulation est-il cohérent ?
- L'ordre de tabulation suit l'ordre du code : le bouton, ses liens, puis la suite.
- Critère 12.11 : Dans chaque page web, les contenus additionnels apparaissant au survol, à la prise de focus ou à l’activation d’un composant d’interface sont-ils si nécessaire atteignables au clavier ?
- Les liens qui apparaissent à l'activation du bouton s'atteignent au clavier.
Autres références
WCAG 2.2
- Understanding SC 1.3.1: Info and Relationships (en anglais)
- Understanding SC 2.1.1: Keyboard (en anglais)
- Understanding SC 2.4.3: Focus Order (en anglais)
- Understanding SC 2.4.7: Focus Visible (en anglais)
- Understanding SC 4.1.2: Name, Role, Value (en anglais)
EN 301 549
- Accessibility requirements for ICT products and services (V4.1.1, PDF) (en anglais)Clauses 9.1.3.1, 9.2.1.1, 9.2.4.3, 9.2.4.7, 9.4.1.2
Pattern APG
- Example Disclosure Navigation Menu (en anglais)
Au-delà de l'APG
| Nouveauté | Apport | Navigateurs | Dans la démo |
|---|---|---|---|
popover et popovertarget | Ouvrent la liste, la referment avec Échap ou un clic ailleurs, et donnent au bouton son état, réduit ou développé. | Chrome 116+, Firefox 125+, Safari 17+ | Oui |
Ancrage CSS (anchor-name, position-anchor) | Place la liste sous son bouton, sans calcul en JavaScript. | Chrome 125+, Firefox 147+, Safari 26+ | Oui |
interestfor | Ouvre la liste au survol et au focus, avec un délai, sans script. | Chrome 149+, Edge 149+ | Non |
Variations
Lien et bouton côte à côte
Le lien « Mon compte » mène à la page d'accueil du compte, et un bouton juste à côté déplie la liste. Chacun garde un seul rôle.
<li>
<a href="/compte">Mon compte</a>
<button
type="button"
popovertarget="account-menu"
aria-label="Pages du compte">▾</button>
<ul id="account-menu" popover>…</ul>
</li>Avec details
details et summary à la place de popover. Ça marche dans de plus vieux navigateurs, mais Échap ne referme pas, et la liste reste ouverte quand on clique ailleurs.
<details>
<summary>Mon compte</summary>
<ul>…</ul>
</details>