English

ARIA, ce poison de l'accessibilité web

Table des matières

L'outil qui ferme les portes

Ouvre les outils de développement sur n'importe quel site. Cherche aria-. Tu vas en trouver partout. Des aria-label, des aria-hidden, des role, des aria-live. En moyenne, 133 attributs ARIA par page sur le million de sites les plus visités au monde. Six fois plus qu'en 2019.

Tu pourrais croire que c'est une bonne nouvelle. Plus d'ARIA, plus d'accessibilité. Sauf que le rapport WebAIM Million 2026 dit exactement l'inverse : les pages qui utilisent ARIA ont 59,1 erreurs d'accessibilité en moyenne, contre 42 pour celles qui n'en utilisent pas. 17 barrières de plus.

Ces pages sont aussi les plus complexes : des applications riches, des tableaux de bord, des interfaces dynamiques. ARIA ne crée pas les erreurs à lui seul, mais sa présence massive signale une complexité qui, mal gérée, produit plus de barrières qu'elle n'en lève. La corrélation est nette, et le résultat est le même : l'outil censé ouvrir les portes en ferme davantage.

Le W3C lui-même le résume en une phrase, dans l'introduction de son ARIA Authoring Practices Guide : "No ARIA is better than bad ARIA."

Cet article va te montrer pourquoi ARIA existe, quelles règles le W3C a posées pour éviter le pire, et comment vérifier en 30 secondes si ton ARIA aide ou empoisonne.

Celle qui entend tes erreurs

Tu ne la connais probablement pas, mais Léonie Watson a passé plus de temps que quiconque à naviguer le web sans le voir, et à expliquer aux développeurs pourquoi leur code ne marche pas.

Léonie a perdu la vue au milieu de la vingtaine, en l'espace de douze mois, suite à une rétinopathie diabétique. Après quelques années de reconstruction, elle est devenue ingénieure en accessibilité, puis co-fondatrice de TetraLogical, puis co-Chair du Board of Directors du W3C. Aujourd'hui, elle navigue le web au lecteur d'écran huit heures par jour. Chaque <div> déguisée en bouton, chaque aria-label qui contredit le texte visible, chaque aria-hidden="true" posé sur un élément interactif, elle les entend.

Et ce qu'elle entend, ça ressemble à ça.

Quand un développeur écrit ceci :

fake-button.html
<div role="button" onclick="save()">
  Enregistrer
</div>

Le lecteur d'écran annonce : "Enregistrer, bouton." Ça semble correct. Et quand Léonie l'active, son lecteur d'écran simule un clic : save() se déclenche. Le piège est ailleurs. Quand elle navigue avec Tab, le faux bouton est invisible, parce qu'une <div> n'est pas focusable par défaut. Et pour un utilisateur clavier sans lecteur d'écran, c'est pire : même en posant le focus dessus avec un tabindex bricolé, Entrée et Espace ne déclenchent rien, parce qu'une <div> n'a aucun comportement clavier natif. Le lecteur d'écran a menti. Il a annoncé un bouton qui n'en offre ni l'accès ni le comportement.

Avec le HTML natif :

real-button.html
<button type="button" onclick="save()">
  Enregistrer
</button>

Même annonce. Mais cette fois, Entrée fonctionne. Tab fonctionne. Le focus est visible. Le bouton est un bouton, pas une <div> qui se fait passer pour un bouton. Zéro ARIA nécessaire.

C'est la leçon que Léonie répète depuis plus de vingt ans : le problème n'est pas qu'il manque d'ARIA, c'est que tu en mets là où le HTML suffit.

La première règle d'ARIA : ne l'utilise pas

Le W3C a publié quatre règles d'utilisation d'ARIA dans Using ARIA. Le document est aujourd'hui archivé ("Discontinued Draft" depuis février 2026), mais ses règles restent la référence, reprises par l'APG. La première est aussi la plus importante :

Si tu peux utiliser un élément HTML natif avec la sémantique et le comportement dont tu as besoin, utilise-le. Ne réinvente pas avec ARIA ce que le HTML fait déjà.

C'est exactement ce que tu viens de voir avec le faux bouton de Léonie. Un <button> est focusable, activable au clavier, annoncé correctement, sans une seule ligne d'ARIA. Une <div role="button"> demande du tabindex, un gestionnaire keydown pour Entrée et Espace, et un rôle explicite. Plus de code, plus de surface de bug, même résultat au mieux, et un résultat dégradé dès que tu oublies un détail.

Les trois autres règles suivent la même logique :

Règle 2 — Ne modifie pas la sémantique native, sauf si tu n'as vraiment pas le choix.

Parfois, le choix est justifié. Quand tu construis un widget que le HTML ne propose pas, comme un système d'onglets ou une arborescence navigable, ARIA doit modifier la sémantique des éléments HTML pour que les technologies d'assistance annoncent correctement le composant. Mais c'est l'exception, pas la règle. Je détaille les cas légitimes et leurs implémentations dans ARIA, ce scalpel de l'accessibilité web.

Règle 3 — Tout contrôle ARIA interactif doit fonctionner au clavier.

Si tu crées un widget avec des rôles ARIA, tu es responsable de tout le comportement clavier. Les touches fléchées pour naviguer, Entrée pour activer, Échap pour fermer. Le HTML natif te donne ce comportement gratuitement. ARIA te donne la sémantique (le rôle, les états, le nom), le comportement, c'est ton code qui doit l'implémenter.

Règle 4 — Ne cache jamais un élément focusable.
hidden-focusable.html
<!-- ❌ Le bouton est masqué pour le lecteur d'écran
     mais reste focusable au clavier -->
<button aria-hidden="true">Fermer</button>
 
<!-- ✅ S'il doit être caché, utilise
     l'attribut HTML natif -->
<button hidden>Fermer</button>

aria-hidden="true" sur un élément focusable crée un fantôme : le lecteur d'écran l'ignore, mais Tab y emmène l'utilisateur. Il arrive sur un élément qui n'a pas de nom, pas de rôle, pas d'existence annoncée. C'est exactement le genre d'expérience qui rend Léonie folle. L'attribut hidden du HTML fait le travail correctement : l'élément disparaît du rendu visuel et de l'arbre d'accessibilité.

Le test décisif

Tu n'as pas besoin d'un audit complet pour savoir si ton ARIA aide ou nuit. Ouvre les outils de développement de ton navigateur, onglet Accessibility : l'arbre d'accessibilité est là. Chaque élément montre son rôle, son nom accessible et ses états ARIA tels que les technologies d'assistance les voient.

Trois vérifications en 30 secondes :

  1. Le nom accessible correspond-il au texte visible ? Clique sur un bouton ou un lien dans l'arbre. Si le Name affiché ne correspond pas à ce que tu lis à l'écran, un utilisateur de navigation vocale ne pourra pas l'activer.

  2. Les rôles sont-ils cohérents ? Un élément annoncé comme "bouton" doit se comporter comme un bouton, focusable et activable au clavier. Si c'est un <div role="button">, appuie sur Tab puis Entrée. Si rien ne se passe, le rôle ment.

  3. Y a-t-il des fantômes ? Navigue avec Tab à travers la page. Si le focus s'arrête sur un élément que l'arbre d'accessibilité ne montre pas, tu as un aria-hidden="true" sur un élément focusable, le piège exact que tu as vu plus haut.

Ce que le RGAA en retient

Le RGAA encadre l'utilisation d'ARIA à travers plusieurs critères, de la compatibilité des scripts avec les technologies d'assistance (7.1) à la pertinence des noms accessibles (11.9). Tous convergent vers la même idée : ARIA n'est pas un outil décoratif. Chaque rôle posé est un engagement, le composant doit se comporter comme ce rôle le promet. Chaque nom accessible est un contrat, il doit correspondre à ce que l'utilisateur voit et peut prononcer.

Tu sais maintenant pourquoi ARIA pose problème et quelles règles le W3C a posées pour limiter les dégâts. Si tu veux savoir quand ARIA est la bonne réponse, quels anti-patterns éviter, et comment tester en profondeur avec un lecteur d'écran : ARIA, ce scalpel de l'accessibilité web.

Sources