Livrer un thème WordPress sur mesure sans vérifier ses rôles ARIA revient à livrer un site sans jamais l’avoir ouvert dans un second navigateur. Le problème avec ARIA, c’est qu’un attribut mal posé ne provoque aucune erreur visible : le site continue de fonctionner normalement à l’écran, tout en envoyant des informations fausses ou contradictoires aux technologies d’assistance.
Notre équipe a construit, projet après projet, une check-list de douze points que nous passons systématiquement en revue avant chaque livraison de thème sur mesure, qu’il s’agisse d’un thème classique en PHP ou d’un thème basé sur des templates de blocs. Voici cette liste, avec le raisonnement derrière chaque point.
Première règle : ARIA ne remplace jamais le HTML natif
Avant même de vérifier un rôle, nous vérifions son absence là où elle ne devrait pas être nécessaire. Un <button role="button"> est redondant ; un <div role="button"> à la place d’un vrai <button> est un choix qui n’apporte que des inconvénients, puisqu’il faut alors recréer manuellement la gestion du focus et de l’activation clavier que l’élément natif offrait gratuitement.
Les douze points de la check-list
- Le menu principal utilise-t-il
<nav aria-label="Navigation principale">et non un simple<div>? - Chaque bouton de sous-menu porte-t-il un attribut
aria-expandedmis à jour dynamiquement ? - Les zones répétées sur toutes les pages (en-tête, pied de page) sont-elles balisées avec
<header>,<footer>ou un rôle équivalent ? - Le fil d’Ariane utilise-t-il
aria-label="Fil d'Ariane"sur son élément<nav>? - Les onglets personnalisés respectent-ils le motif
role="tablist",role="tab",role="tabpanel"avecaria-selectedà jour ? - Les fenêtres modales portent-elles
role="dialog"etaria-modal="true"? - Chaque modale a-t-elle un titre référencé par
aria-labelledby? - Les messages d’erreur de formulaire sont-ils annoncés via
aria-live="polite"ou associés au champ pararia-describedby? - Les icônes purement décoratives portent-elles
aria-hidden="true"? - Aucun élément ne porte-t-il de rôle ARIA en contradiction avec sa balise native, comme
role="heading"sur un<div>alors qu’un<h2>ferait exactement la même chose ? - Les régions principales de la page sont-elles identifiables par un lecteur d’écran via
<main>et non un simple identifiant CSS ? - Les attributs
aria-hidden="true"ne sont-ils jamais posés par erreur sur un ancêtre contenant du contenu focusable ?

Le point douze mérite un exemple concret
Ce dernier point du dernier projet audité concernait un panneau de recherche masqué visuellement mais laissé dans le flux du DOM avec aria-hidden="true" posé sur son conteneur parent, sans que le champ de recherche à l’intérieur ne soit retiré de l’ordre de tabulation. Résultat : un utilisateur de clavier tombait, via Tab, sur un champ de recherche invisible à l’écran, tandis qu’un lecteur d’écran, respectant l’attribut aria-hidden, ignorait purement et simplement ce même champ. Les deux publics rencontraient chacun un bug différent, provoqué par la même erreur.
<div aria-hidden="true" class="search-panel">
<input type="search" tabindex="0">
</div>
La correction consistait à retirer également l’input de l’ordre de tabulation, avec tabindex="-1", tant que le panneau reste fermé, puis à restaurer tabindex="0" à son ouverture.
Comment nous appliquons cette check-list
Chaque point est vérifié de deux façons complémentaires : une lecture du code source pour repérer les rôles et attributs posés, puis un passage clavier complet de la page pour confirmer que le comportement réel correspond à ce que le code prétend annoncer. La lecture de code seule ne suffit jamais, car un attribut aria-expanded peut très bien exister dans le HTML sans jamais être mis à jour par le JavaScript associé.
Un rôle ARIA posé et jamais mis à jour dynamiquement ment à l’utilisateur avec autant d’aplomb qu’un mensonge tout court. Un attribut figé est souvent plus dangereux qu’une absence totale d’attribut.
En résumé
Cette check-list de douze points prend environ une demi-journée à parcourir sur un thème de taille moyenne, et elle a permis de rattraper, projet après projet, des erreurs qu’aucun outil automatisé de type lecteur de code n’aurait détectées seul, faute de pouvoir observer le comportement dynamique réel de la page. Nous la faisons évoluer à chaque nouveau projet lorsqu’un cas inédit apparaît, mais son socle reste stable depuis maintenant plusieurs livraisons consécutives.