Rôles ARIA expliqués : quand et comment utiliser ARIA en HTML

17 min read

ARIA (Applications Internet Riches Accessibles) offre aux développeurs une boîte à outils puissante pour rendre des interfaces web dynamiques et complexes accessibles aux utilisateurs de lecteurs d’écran — mais les mauvais usages sont répandus et coûteux. Ce guide décompose chaque grande catégorie de rôles ARIA, explique les règles d’or de l’utilisation d’ARIA et vous montre des exemples de code concrets afin que vous puissiez l’appliquer correctement.

Voici un chiffre qui donne à réfléchir : selon l’analyse de WebAIM portant sur la page d’accueil du top un million de sites web, les pages qui incluent des attributs ARIA présentent en moyenne significativement plus d’erreurs d’accessibilité détectables que les pages sans ARIA. Ce n’est pas un argument contre l’utilisation d’ARIA — c’est un argument en faveur de son utilisation correcte. ARIA est l’un des outils les plus puissants de la boîte à outils d’accessibilité moderne, mais aussi l’un des plus mal compris. Bien utilisé, il ouvre réellement votre site à des millions d’utilisateurs en situation de handicap. Mal utilisé, il dégrade activement leur expérience.

Qu’est-ce qu’ARIA et pourquoi cela existe-t-il ?

ARIA signifie Accessible Rich Internet Applications. Il s’agit d’un ensemble d’attributs HTML, définis par l’Initiative pour l’Accessibilité du Web (WAI) du W3C, qui permet aux développeurs de communiquer des informations sémantiques aux technologies d’assistance telles que les lecteurs d’écran, les afficheurs braille et les logiciels de commande vocale. Lorsqu’un navigateur rend une page, il construit deux structures parallèles : le DOM (ce que vous voyez) et l’Arbre d’Accessibilité (ce que lisent les technologies d’assistance). Les attributs ARIA vous permettent de modifier cet Arbre d’Accessibilité pour décrire avec précision ce que sont les composants personnalisés et comment ils se comportent.

Le besoin d’ARIA est né d’un problème réel. HTML a été conçu pour des documents, pas pour des applications. Quand le web a évolué vers une plateforme d’expériences riches et interactives — interfaces à onglets, boîtes de dialogue modales, glisser-déposer, flux de données en direct — les éléments HTML natifs ne pouvaient pas transmettre à un lecteur d’écran ce que ces composants étaient ni comment ils fonctionnaient. ARIA comble cette lacune. Comme le formule MDN, ARIA « complète HTML afin que les interactions et widgets couramment utilisés dans les applications puissent être transmis aux technologies d’assistance lorsqu’il n’existe pas d’autre mécanisme ».

ARIA ne modifie pas la présentation visuelle. Il n’ajoute pas de comportement. Il ne fournit pas automatiquement la prise en charge du clavier. Il modifie uniquement ce que l’Arbre d’Accessibilité expose à la technologie d’assistance. C’est une distinction importante — et l’une des causes de nombreuses erreurs commises par les développeurs lorsqu’ils utilisent ARIA comme raccourci.

La spécification est maintenue par le W3C sous le nom WAI-ARIA, actuellement en version 1.2, avec la 1.3 en cours de développement. Elle fournit une ontologie de rôles, d’états et de propriétés qui, ensemble, décrivent des éléments d’interface utilisateur accessibles couvrant l’ensemble des modèles web modernes.

Les trois piliers : rôles, états et propriétés

Avant d’écrire une seule ligne d’ARIA, vous devez comprendre les trois blocs de construction distincts que fournit la spécification. Ils ne sont pas interchangeables, et les confondre est l’une des sources d’erreurs les plus fréquentes.

Les rôles définissent ce qu’un élément est. Un rôle répond à la question : quel type de chose suis-je en train de regarder ? Parmi les exemples, on trouve button, dialog, navigation, tablist et progressbar. Vous appliquez un rôle avec l’attribut role : <div role='button'>. Le rôle communique la finalité de l’élément à la technologie d’assistance afin que l’utilisateur sache comment interagir avec lui.

Les états décrivent la condition dynamique d’un élément — quelque chose qui change au fur et à mesure que l’utilisateur interagit avec la page. L’attribut aria-expanded indique à un lecteur d’écran si une section repliable est ouverte ou fermée. aria-checked reflète si une case à cocher personnalisée est cochée. Les états doivent être maintenus synchronisés avec JavaScript ; un aria-expanded='false' statique qui ne change jamais n’est pas seulement inutile, il est activement trompeur.

Les propriétés fournissent des informations descriptives, généralement plus stables, sur un élément. aria-label donne à un élément un nom accessible qui remplace son texte visible. aria-labelledby pointe vers un autre élément dont le texte sert d’étiquette. aria-describedby relie à un texte descriptif complémentaire. aria-required signale qu’un champ de formulaire doit être rempli. Alors que l’on s’attend à ce que les états changent fréquemment, les propriétés ont tendance à être définies une fois pour toutes — même s’il existe des exceptions.

Les rôles définissent ce qu’est un élément. Les états définissent comment il se comporte à l’instant présent. Les propriétés fournissent un contexte descriptif supplémentaire. Vous avez besoin des trois, travaillant ensemble, pour produire un composant personnalisé pleinement accessible.

La règle d’or — et pourquoi elle compte plus que vous ne le pensez

La première règle d’utilisation d’ARIA du W3C est sans ambiguïté : si vous pouvez utiliser un élément ou un attribut HTML natif dont la sémantique et le comportement répondent déjà à vos besoins, utilisez-le. Ne vous tournez pas vers ARIA en premier. On parle parfois du principe « pas d’ARIA vaut mieux que de la mauvaise ARIA » — une formule qui reflète le danger bien réel d’une utilisation d’ARIA pleine de bonnes intentions mais incorrecte.

Les éléments HTML natifs embarquent gratuitement des sémantiques ARIA implicites. Un élément <button> est déjà exposé à l’Arbre d’Accessibilité en tant que bouton. Il est déjà focalisable au clavier. Il réagit déjà aux touches Entrée et Espace. Il annonce déjà son étiquette. Au moment où vous écrivez <div role='button'>, vous assumez la responsabilité de recréer manuellement tout ce comportement — la gestion du clavier, la gestion du focus, la mise à jour des états — en JavaScript. Ce n’est pas une préoccupation théorique. Oublier la prise en charge clavier sur un bouton personnalisé est l’une des erreurs ARIA les plus courantes et les plus préjudiciables en production.

Les cas où ARIA est réellement nécessaire se concentrent généralement autour de quelques scénarios : lorsque vous construisez un widget complexe qui n’a pas d’équivalent HTML (un carrousel, une boîte combinée avec autocomplétion, une vue arborescente) ; lorsque vous corrigez un balisage existant où restructurer le DOM est trop coûteux ; lorsque vous construisez un composant web qui doit exposer des sémantiques personnalisées ; ou lorsque la prise en charge par les navigateurs et les technologies d’assistance d’un élément natif est suffisamment incohérente pour que l’équivalent ARIA fonctionne plus fiablement en pratique.

En dehors de ces scénarios, votre premier réflexe devrait toujours être le HTML sémantique. Utilisez <nav> plutôt que <div role='navigation'>. Utilisez <main> plutôt que <div role='main'>. Utilisez <button> plutôt que <div role='button'>. Les éléments natifs sont plus robustes, mieux pris en charge et nécessitent beaucoup moins de maintenance.

Tour d’horizon des principales catégories de rôles ARIA

La spécification WAI-ARIA organise les rôles en plusieurs catégories. Comprendre ces catégories vous aide à savoir quel rôle utiliser et quand.

Rôles de repère (landmark)

Les rôles de repère marquent les grandes régions d’une page, permettant aux utilisateurs de lecteurs d’écran de passer directement aux sections clés à l’aide de raccourcis clavier. Les rôles de repère les plus couramment utilisés sont banner, navigation, main, complementary, contentinfo, search et form. Chacun d’eux possède un équivalent HTML natif direct : <header>, <nav>, <main>, <aside>, <footer>, etc. En pratique, cela signifie que les rôles de repère sont presque toujours redondants si vous utilisez du HTML sémantique moderne. Ajoutez-les uniquement lorsque vous êtes contraint à un balisage non sémantique pour des raisons structurelles.

<!-- Prefer this -->
<header>
  <nav>...</nav>
</header>
<main>...</main>
<footer>...</footer>

<!-- Use ARIA only when you must use divs -->
<div role='banner'>
  <div role='navigation'>...</div>
</div>
<div role='main'>...</div>
<div role='contentinfo'>...</div>

Rôles de widget

Les rôles de widget décrivent des composants interactifs que l’utilisateur manipule directement. C’est là qu’ARIA accomplit son travail le plus important, car de nombreux modèles de widgets n’ont pas d’équivalent HTML natif. Parmi les rôles de widget courants, on trouve button, checkbox, dialog, menu, menuitem, slider, tablist, tab, tabpanel, tooltip, tree et combobox.

Lorsque vous utilisez un rôle de widget, vous assumez l’entière responsabilité de l’interaction clavier. Le WAI-ARIA Authoring Practices Guide (APG) définit les schémas de clavier attendus pour chaque type de widget — par exemple, les flèches pour se déplacer entre les onglets, Échap pour fermer une boîte de dialogue, Origine et Fin pour aller au premier et au dernier élément d’une liste. Ne pas implémenter ces schémas signifie que votre composant est techniquement étiqueté mais pratiquement inutilisable pour les utilisateurs qui n’utilisent que le clavier.

<!-- A custom tab interface -->
<div role='tablist' aria-label='Account settings'>
  <button role='tab' aria-selected='true' aria-controls='panel-profile' id='tab-profile'>
    Profile
  </button>
  <button role='tab' aria-selected='false' aria-controls='panel-security' id='tab-security' tabindex='-1'>
    Security
  </button>
</div>
<div role='tabpanel' id='panel-profile' aria-labelledby='tab-profile'>
  <p>Profile settings content</p>
</div>
<div role='tabpanel' id='panel-security' aria-labelledby='tab-security' hidden>
  <p>Security settings content</p>
</div>

Rôles de région dynamique (live region)

Les régions dynamiques sont l’une des fonctionnalités les plus réellement utiles d’ARIA. Elles permettent aux technologies d’assistance d’annoncer les mises à jour de contenu dynamiques — messages de statut, notifications d’erreur, messages de chat, indicateurs de chargement — aux utilisateurs qui ne peuvent pas voir le changement à l’écran. Sans régions dynamiques, un utilisateur de lecteur d’écran qui soumet un formulaire pourrait ne jamais savoir s’il a réussi ou échoué, à moins que le focus ne soit explicitement déplacé vers le résultat.

Les rôles de région dynamique principaux sont alert, status, log, marquee et timer. Le rôle alert porte implicitement le paramètre aria-live='assertive', ce qui signifie qu’il interrompt immédiatement l’utilisateur — approprié pour les erreurs ou les avertissements urgents. Le rôle status utilise aria-live='polite', attendant que l’utilisateur ait terminé sa tâche en cours avant d’annoncer — idéal pour les messages de succès et les indicateurs de progression.

<!-- Polite status message for non-urgent feedback -->
<div role='status' aria-live='polite' aria-atomic='true'>
  <!-- Dynamically inject text here with JavaScript -->
</div>

<!-- Assertive alert for errors that demand immediate attention -->
<div role='alert'>
  Please correct the errors below before submitting.
</div>

La clé des régions dynamiques est que le conteneur doit être présent dans le DOM avant que le contenu dynamique ne soit injecté. Une région dynamique créée et peuplée simultanément est fréquemment manquée par les lecteurs d’écran. Créez le conteneur au chargement de la page et remplissez-le avec JavaScript au fur et à mesure que les événements se produisent.

Rôles de structure de document

Les rôles de structure de document — tels que article, list, listitem, table, row, cell, figure et heading — décrivent l’organisation structurelle du contenu. La plupart d’entre eux sont désormais supplantés par des éléments HTML natifs, et MDN note que la majorité des rôles de structure de document « ne devraient plus être utilisés, car les navigateurs prennent désormais en charge des éléments HTML sémantiques ayant la même signification ». La principale exception est lorsque vous travaillez avec des environnements de rendu personnalisés, des composants web ou du contenu basé sur SVG où les éléments HTML natifs ne sont pas disponibles.

Propriétés ARIA essentielles que chaque développeur devrait connaître

Au-delà des rôles, plusieurs propriétés ARIA apparaissent constamment dans le travail d’accessibilité en conditions réelles. Ce sont celles que vous utiliserez le plus souvent :

  • aria-label : fournit un nom accessible pour un élément lorsqu’aucune étiquette textuelle visible n’est disponible ou lorsque le texte visible est insuffisant. Cas d’usage courants : boutons composés uniquement d’icônes, champs de recherche sans étiquette visible, boutons de fermeture de modales. Notez que aria-label remplace tout texte visible ou étiquette native, utilisez-le donc avec précaution sur les éléments qui ont déjà un texte visible.
  • aria-labelledby : pointe vers un ou plusieurs éléments dont le contenu textuel sert de nom accessible. Plus robuste que aria-label pour les cas complexes, car le texte de l’étiquette reste synchronisé avec le contenu visible. Accepte une liste d’ID d’éléments séparés par des espaces, et les technologies d’assistance concatènent les textes référencés dans l’ordre.
  • aria-describedby : relie à un texte de description complémentaire — pas un nom, mais un contexte supplémentaire. Utilisez-le pour relier des champs de formulaire à leurs messages d’erreur, ou pour associer une info-bulle à l’élément qu’elle décrit. Les lecteurs d’écran annoncent généralement ceci après le nom et le rôle de l’élément.
  • aria-hidden : retire complètement un élément de l’Arbre d’Accessibilité. Inestimable pour les icônes décoratives, le contenu dupliqué et les éléments purement visuels qui créeraient du bruit pour les utilisateurs de lecteurs d’écran. N’appliquez jamais aria-hidden='true' à un élément focalisable — un utilisateur pourrait toujours y accéder au clavier, mais ne recevrait aucune information à son sujet.
  • aria-expanded : communique si un élément repliable — menu déroulant, accordéon ou widget de divulgation — est actuellement ouvert ou fermé. Doit être basculé dynamiquement avec JavaScript ; une valeur statique est pire que l’absence de l’attribut.
  • aria-current : indique l’élément courant au sein d’un ensemble, le plus souvent utilisé pour la navigation afin de marquer le lien de page actif (aria-current='page') ou l’étape actuelle dans un processus en plusieurs étapes.

Erreurs ARIA courantes qui nuisent réellement à l’accessibilité

Étant donné que les pages avec ARIA ont tendance à présenter plus d’erreurs d’accessibilité que celles qui n’en ont pas, il vaut la peine d’être explicite sur ce qui se passe le plus souvent mal. Ce ne sont pas des cas limites — ce sont des schémas qui apparaissent chaque jour dans du code en production.

Utiliser des rôles ARIA sur des éléments à forte sémantique native. Certains éléments HTML ont ce que la spécification appelle une « forte sémantique native » — des significations profondément intégrées au navigateur et qui ne peuvent pas être remplacées en toute sécurité. Placer un rôle inapproprié sur un <button> ou un <input> peut amener le navigateur à ignorer complètement le rôle ARIA, ou produire un comportement contradictoire qui perturbe les technologies d’assistance. Le rôle que vous déclarez doit être approprié pour l’élément sur lequel vous l’appliquez.

Oublier la prise en charge clavier avec les rôles de widget. Le role='button' d’ARIA indique à un lecteur d’écran que l’élément est un bouton. Il ne rend pas l’élément opérable au clavier. Si vous utilisez un <div> avec role='button', vous devez ajouter tabindex='0' pour le rendre focalisable, et vous devez ajouter des écouteurs d’événements pour les touches Entrée et Espace. Oublier l’un de ces éléments casse l’expérience pour les utilisateurs qui n’utilisent que le clavier.

<!-- Incomplete and inaccessible -->
<div role='button' onclick='doSomething()'>Submit</div>

<!-- Correct custom button implementation -->
<div
  role='button'
  tabindex='0'
  onclick='doSomething()'
  onkeydown='if(event.key==="Enter"||event.key===" ")doSomething()'
>Submit</div>

<!-- Or, the right answer: just use a button -->
<button onclick='doSomething()'>Submit</button>

Utiliser aria-hidden sur des éléments focalisables. Appliquer aria-hidden='true' à un élément focalisable le masque dans l’Arbre d’Accessibilité mais pas de la navigation au clavier. Un utilisateur au clavier peut toujours y accéder par tabulation, ne recevoir aucune information à son sujet et ne pas savoir ce qu’il fait. Il s’agit d’un échec WCAG 2.1 au regard du critère de succès 4.1.2 (Nom, rôle, valeur).

États ARIA obsolètes. Ne pas mettre à jour aria-expanded, aria-checked, aria-selected et des états similaires lorsque l’interface change laisse les utilisateurs de lecteurs d’écran avec une vision fondamentalement incorrecte de l’interface. Un menu qui s’ouvre visuellement mais dont le déclencheur indique toujours aria-expanded='false' est activement trompeur.

Rôles redondants. Ajouter role='navigation' à un élément <nav>, ou role='button' à un <button>, n’apporte rien d’utile. Cela encombre le code et peut occasionnellement perturber certaines combinaisons de technologies d’assistance. Faites confiance aux sémantiques natives.

ARIA et WCAG : comprendre le lien

ARIA n’est pas WCAG. Ce sont des spécifications distinctes qui fonctionnent ensemble. WCAG (Web Content Accessibility Guidelines) définit le quoi — les résultats requis pour un contenu accessible. ARIA fait partie du comment — un mécanisme technique pour atteindre certains de ces résultats. Le critère de succès WCAG le plus pertinent pour ARIA est le 4.1.2 : Nom, rôle, valeur, qui exige que tous les composants d’interface utilisateur aient un nom, exposent leur rôle aux technologies d’assistance et communiquent leur état et leurs propriétés de manière programmatique. ARIA est l’un des principaux outils pour satisfaire ce critère pour les composants personnalisés.

ARIA contribue également à plusieurs autres critères de succès. Les rôles de repère contribuent au 2.4.1 (Contourner des blocs) en permettant la navigation de contournement. Les régions dynamiques sont souvent l’outil approprié pour répondre au 4.1.3 (Messages d’état) dans WCAG 2.1, qui exige que les messages d’état soient déterminables de manière programmatique sans recevoir le focus. L’utilisation correcte de aria-label et aria-labelledby aide à satisfaire 2.4.6 (Titres et étiquettes) et 1.3.1 (Information et relations).

Il convient de noter que la conformité WCAG est de plus en plus une exigence légale. L’Acte européen sur l’accessibilité est pleinement entré en vigueur en juin 2025, étendant les exigences d’accessibilité obligatoires à un large éventail de services numériques du secteur privé dans les États membres de l’UE. Aux États-Unis, l’ADA continue d’être interprétée comme incluant l’accessibilité web, et les exigences fédérales au titre de la Section 508 s’appliquent aux organismes gouvernementaux et aux organisations financées par des fonds fédéraux. Comprendre correctement ARIA n’est pas seulement une bonne pratique — cela fait de plus en plus partie de vos obligations de conformité.

Tester votre implémentation ARIA

La seule façon de savoir si votre implémentation ARIA fonctionne réellement est de la tester avec de vraies technologies d’assistance. Les outils automatisés comme axe, WAVE et Lighthouse peuvent détecter des violations structurelles — une propriété requise manquante, un rôle invalide, un aria-hidden appliqué à un élément focalisable — mais ils ne peuvent pas vous dire si un lecteur d’écran annonce votre modale de manière compréhensible, ni si la navigation au clavier dans votre widget arborescent personnalisé suit les schémas attendus.

Pour les tests manuels, les principaux lecteurs d’écran à couvrir sont JAWS et NVDA sur Windows (ensemble, ils représentent la grande majorité de l’usage des lecteurs d’écran sur desktop), et VoiceOver sur macOS et iOS. TalkBack couvre Android. Chaque combinaison lecteur d’écran/navigateur peut se comporter différemment, il est donc fortement recommandé de tester au moins deux combinaisons. Testez chaque état interactif : ouvrez la boîte de dialogue, déployez l’accordéon, sélectionnez l’option, déclenchez l’alerte. Vérifiez que l’annonce correspond à ce qu’un utilisateur voyant comprendrait en regardant la même interface.

Lors du test de widgets personnalisés, parcourez le modèle d’interaction clavier défini dans le WAI-ARIA Authoring Practices Guide pour ce type de widget. Si votre liste d’onglets ne répond pas aux flèches, ou si votre boîte de dialogue ne piège pas le focus, ce sont des échecs, quel que soit le degré de correction du balisage ARIA dans un audit automatisé.

Points clés à retenir

  • Préférez toujours le HTML sémantique à ARIA. Les éléments natifs comme <button>, <nav>, <main> et <dialog> embarquent des sémantiques d’accessibilité intégrées plus robustes et nécessitant beaucoup moins de code que leurs équivalents ARIA-sur-un-div. Ne recourez à ARIA que lorsque le HTML natif est réellement insuffisant.
  • Les rôles ARIA sont un engagement, pas un raccourci. Appliquer role='button' ou role='dialog' à un élément personnalisé vous engage à implémenter le modèle complet d’interaction clavier pour ce type de widget. Des rôles sans comportement correspondant créent de la confusion et des échecs WCAG.
  • Gardez les états ARIA synchronisés avec votre interface. Les attributs dynamiques comme aria-expanded, aria-checked, aria-selected et le contenu aria-live doivent être mis à jour en JavaScript au fur et à mesure que l’interface évolue. Un état obsolète est activement nuisible — il communique une information erronée à l’utilisateur.
  • Utilisez des régions dynamiques pour les mises à jour de contenu. Tout contenu qui se met à jour sans rechargement de page — notifications, messages d’erreur, états de chargement, flux de chat — a besoin d’une région aria-live ou d’un rôle approprié comme alert ou status afin que les utilisateurs de lecteurs d’écran reçoivent automatiquement la même information que les utilisateurs voyants.
  • Testez avec de vraies technologies d’assistance, pas seulement avec des outils automatisés. Les analyseurs automatisés détectent les erreurs ARIA structurelles mais ne peuvent pas vérifier si votre implémentation produit une expérience cohérente et utilisable. Les tests manuels avec JAWS, NVDA et VoiceOver sont le seul moyen de combler cette lacune.