Le critère 7.1 demande que tout composant interactif réalisé en JavaScript soit utilisable au clavier et correctement exposé aux technologies d'assistance. C'est le critère le plus large du RGAA : il couvre menus déroulants, modals, carrousels, onglets, accordéons, autocomplétions, paniers dynamiques — tout ce qui réagit sans recharger la page.
Les 3 questions à poser pour chaque widget
- 01Est-il atteignable au clavier (Tab) et activable (Enter / Espace) ?
- 02Annonce-t-il son rôle (bouton, menu, dialogue) au lecteur d'écran ?
- 03Annonce-t-il ses changements d'état (ouvert/fermé, sélectionné, occupé) ?
Si la réponse aux trois est oui, le composant est probablement conforme. Si l'une est non, il y a un trou — et c'est presque toujours la question 1 (le clavier) ou la question 3 (l'état) qui pèche.
Le piège fondateur : le div cliquable
⚠ Le piège du <div onclick>
Un `<div onclick="...">` n'est pas atteignable au clavier et n'est pas un bouton pour un lecteur d'écran. Solution : un `<button type="button">` natif, qui gère le focus, Enter et Espace gratuitement. La règle d'or : n'inventez un élément interactif que si aucun élément HTML natif ne fait déjà le travail.
Rôle, nom, état : le trio ARIA
Quand un élément natif ne suffit pas, ARIA comble le manque selon trois axes. Le rôle (`role="tab"`, `role="dialog"`…) dit ce qu'est l'élément. Le nom accessible (texte, `aria-label`, `aria-labelledby`) dit à quoi il sert. L'état (`aria-expanded`, `aria-selected`, `aria-checked`, `aria-busy`) dit dans quelle situation il se trouve. Un widget qui a un rôle mais pas d'état mis à jour ment au lecteur d'écran.
Patterns ARIA standards
L'ARIA Authoring Practices Guide (APG) maintient un catalogue de patterns vérifiés : combobox, dialog, disclosure, listbox, menu, tabs, treeview — avec la gestion clavier attendue pour chacun. Si votre composant correspond à un pattern, suivez-le à la lettre, y compris les flèches directionnelles attendues. Sinon, vous ferez très probablement pire qu'avec du HTML natif.
La gestion du focus, angle mort habituel
- →À l'ouverture d'une modal : le focus entre dans la modal, et y reste piégé tant qu'elle est ouverte
- →À la fermeture : le focus revient sur l'élément qui l'a déclenchée
- →Après une action dynamique (ajout au panier) : annoncer le changement via une zone `aria-live`
- →Jamais d'`outline: none` sans indicateur de focus de remplacement (c'est le critère 10.7)
// Ne réinventez pas la roue
Reka UI (utilisé par ComplAudit), Radix Vue, Headless UI : ces kits implémentent les patterns APG (focus, clavier, ARIA) correctement. En 2026, écrire un menu ou une modal accessible à la main from scratch, c'est s'exposer à rater au moins une des règles.
Questions fréquentes
axe-core suffit-il à valider un widget JS ?
Non. axe-core détecte les attributs ARIA invalides et les rôles manquants, mais il ne sait pas si votre menu se pilote vraiment au clavier ni si l'état annoncé correspond à la réalité. Ces points demandent un test manuel au clavier et au lecteur d'écran.
Tout doit-il vraiment être pilotable au clavier ?
Oui : toute action réalisable à la souris doit l'être au clavier. C'est la base du critère 7.1. Un survol qui révèle une information doit aussi pouvoir se déclencher au focus clavier.
aria-live, c’est pour quoi ?
Pour annoncer un changement dynamique sans déplacer le focus : "Produit ajouté au panier", "3 résultats trouvés". Une région `aria-live="polite"` lit le nouveau contenu dès qu'il apparaît, sans interrompre l'utilisateur.
Vérifier que vos composants dynamiques sont bien exposés aux lecteurs d'écran :
→ Lancer un audit