Courant Mis à jour : 2026-04

Propriétés et états ARIA : Les attributs essentiels

Les attributs ARIA qui apparaissent dans la grande majorité des situations réelles, organisés en trois familles : états de composant, relations et associations, informations contextuelles. Inclut les attributs de relation avancés (aria-owns, aria-flowto, aria-posinset, aria-keyshortcuts).

Table des matières

WAI-ARIA définit 48 propriétés et états. En audit et en intégration, un sous-ensemble d’entre eux revient dans la grande majorité des situations. Cet article les couvre en détail, organisés en trois familles selon leur fonction — des états de composant les plus courants aux attributs de relation avancés.

Propriété vs état, une distinction utile : les propriétés décrivent des caractéristiques stables (aria-label, aria-required, aria-haspopup). Les états décrivent des conditions qui changent en réponse aux interactions de l’utilisateur (aria-expanded, aria-checked, aria-disabled). En pratique, les deux s’utilisent comme attributs HTML.

Famille 1 : États de composant

Ces attributs communiquent la condition actuelle d’un composant interactif. Ils doivent être mis à jour dynamiquement via JavaScript quand l’état change. Un aria-expanded="false" qui reste faux après ouverture est une erreur.

aria-expanded

Indique si un élément contrôlé est déplié ou replié. S’applique au déclencheur, pas au contenu contrôlé.

<!-- Accordéon -->
<button aria-expanded="false" aria-controls="contenu-1">
  Quels sont les horaires ?
</button>
<div id="contenu-1" hidden>
  Ouvert du lundi au vendredi, 9h-17h.
</div>

<!-- Après clic — mettre à jour aria-expanded ET afficher le contenu -->
<button aria-expanded="true" aria-controls="contenu-1">
  Quels sont les horaires ?
</button>
<div id="contenu-1">
  Ouvert du lundi au vendredi, 9h-17h.
</div>
→ NVDA fermé : "Quels sont les horaires ?, bouton réduit"
→ NVDA ouvert : "Quels sont les horaires ?, bouton développé"

Valeurs : "true" | "false". Pas de valeur "undefined" ou "null". L’attribut doit être présent ou absent, jamais avec une valeur vide.

Erreur fréquente : mettre aria-expanded sur le contenu plutôt que sur le déclencheur. Le lecteur d’écran annonce l’état quand il atteint le bouton, pas quand il entre dans le contenu.

Critères RGAA : 7.1 , 7.3 .


aria-selected

Indique l’élément sélectionné dans un groupe de sélection : onglets, listbox, treeview. À ne pas confondre avec aria-checked (cases à cocher) ni aria-pressed (toggle buttons).

<!-- Interface à onglets -->
<div role="tablist">
  <button role="tab" aria-selected="true"  id="tab-infos">Informations</button>
  <button role="tab" aria-selected="false" id="tab-docs"  tabindex="-1">Documents</button>
</div>
→ NVDA : "Informations, onglet sélectionné, 1 sur 2"
→ NVDA : "Documents, onglet, 2 sur 2"

Valeurs : "true" | "false". Dans un tablist, un seul onglet a aria-selected="true" à la fois. Tous les autres ont explicitement "false" . Attention à ne pas omettre l’attribut sur les non-sélectionnés.

Critère RGAA : 7.1 .


aria-checked

État d’une case à cocher, d’un radio, ou d’un switch. Supporte un troisième état "mixed" pour les cases à cocher partiellement cochées (sélection partielle d’un groupe).

<!-- Case à cocher custom -->
<div role="checkbox" aria-checked="false" tabindex="0">
  Recevoir la newsletter
</div>

<!-- État indéterminé — sélection partielle -->
<div role="checkbox" aria-checked="mixed" tabindex="0">
  Sélectionner tout (3 sur 7 sélectionnés)
</div>
→ NVDA coché   : "Recevoir la newsletter, case à cocher cochée"
→ NVDA décoché : "Recevoir la newsletter, case à cocher non cochée"
→ NVDA mixed   : "Sélectionner tout, case à cocher partiellement cochée"

Valeurs : "true" | "false" | "mixed".

Rappel : si <input type="checkbox"> est possible, l’utiliser. aria-checked est réservé aux composants custom.

Critère RGAA : 7.1 .


aria-pressed

État d’un bouton bascule (toggle button) : bouton qui reste activé après clic. Différent d’aria-checked : aria-pressed s’applique aux boutons, aria-checked aux contrôles de formulaire.

<!-- Bouton gras dans un éditeur de texte -->
<button aria-pressed="false">
  <strong>G</strong>
  <span class="sr-only">Gras</span>
</button>

<!-- Après activation -->
<button aria-pressed="true">
  <strong>G</strong>
  <span class="sr-only">Gras</span>
</button>
→ NVDA inactif : "Gras, bouton non activé"
→ NVDA actif   : "Gras, bouton activé"

Erreur fréquente : utiliser aria-pressed sur un bouton qui navigue vers une page ou ouvre une modale. aria-pressed implique un état persistant, c’est pour les toggles uniquement.

Critère RGAA : 7.1 .


aria-disabled

Indique qu’un élément est désactivé mais reste visible dans l’arbre d’accessibilité et focusable au clavier.

C’est la différence fondamentale avec l’attribut HTML disabled.

disabled (HTML)aria-disabled="true" (ARIA)
Focusable au clavierNonOui
Dans l’arbre d’accessibilitéOui (annoncé “grisé”)Oui (annoncé “désactivé”)
Soumis avec le formulaireNonOui (si <input>)
CliquableNonNon (à implémenter)

Quand utiliser aria-disabled : quand tu veux que l’utilisateur puisse atteindre l’élément pour comprendre pourquoi il est désactivé, et potentiellement lire une explication via aria-describedby.

<!-- Bouton désactivé mais atteignable, avec explication -->
<button
  aria-disabled="true"
  aria-describedby="raison-desactivation"
  onclick="return false"
>
  Soumettre
</button>
<p id="raison-desactivation" class="sr-only">
  Remplissez tous les champs obligatoires pour soumettre le formulaire.
</p>
Attention : aria-disabled="true" n’empêche pas les clics, il faut gérer onclick="return false" ou équivalent en JavaScript.

Critère RGAA : 7.1 , 11.1 .


aria-hidden

Retire un élément et tous ses descendants de l’arbre d’accessibilité. Les technologies d’assistance (AT) l’ignorent complètement.

<!-- ✓ Icône décorative dans un lien avec texte -->
<a href="/accueil">
  <svg aria-hidden="true" focusable="false">...</svg>
  Accueil
</a>

<!-- ✓ Contenu répété masqué aux AT -->
<span aria-hidden="true">★★★☆☆</span>
<span class="sr-only">3 étoiles sur 5</span>

Les trois règles d’aria-hidden :

  1. Jamais sur un élément focusable : <a>, <button>, <input>, <select>, <textarea>. Crée un piège clavier silencieux.
  2. Jamais sur un ancêtre d’un élément focusable : masque le parent, l’élément focusable reste atteignable mais muet.
  3. Toujours accompagner focusable="false" sur les SVG : certains navigateurs anciens rendent les SVG focusables par défaut.
<!-- ✗ Catastrophe — bouton focusable masqué aux AT -->
<button aria-hidden="true">Fermer</button>

<!-- ✗ Catastrophe — lien focusable dans un parent masqué -->
<div aria-hidden="true">
  <a href="/contact">Contact</a>
</div>

<!-- ✓ SVG décoratif correctement masqué -->
<svg aria-hidden="true" focusable="false" viewBox="0 0 24 24">
  <path d="..."/>
</svg>

Critères RGAA : 1.2 (images décoratives) , 10.8 (contenus cachés) .

Famille 2 : Relations et associations

Ces attributs établissent des liens sémantiques entre éléments. Ils permettent aux AT de comprendre qu’un label décrit un champ, qu’un message d’erreur concerne un input, qu’un bouton contrôle un panneau.

aria-label, aria-labelledby, aria-describedby

Trois attributs pour nommer et décrire les éléments. Ils se complètent sans se substituer.

Hiérarchie de priorité pour le nom accessible (de la plus prioritaire à la moins) :

  1. aria-labelledby
  2. aria-label
  3. Texte natif de l’élément (<label>, texte visible, attribut alt…)
  4. aria-describedby : jamais utilisé comme nom, toujours comme description complémentaire

aria-label : nom textuel inline, invisible à l’écran.

<!-- Bouton avec icône seule -->
<button aria-label="Fermer la fenêtre de dialogue">
  <svg aria-hidden="true"><!-- icône × --></svg>
</button>

<!-- Zone de recherche sans label visible -->
<input type="search" aria-label="Rechercher dans le site">

À utiliser quand il n’y a pas de texte visible à référencer, ou quand le texte visible est insuffisant.

Règle critique : Label in Name (WCAG 2.5.3). Quand un élément interactif a un texte visible et un aria-label, l’aria-label doit contenir intégralement le texte visible. Sinon, les utilisateurs de commande vocale qui dictent le texte affiché ne déclenchent rien : le système cherche le nom accessible, pas le visuel.
<!-- ✗ Mauvais : aria-label différent du texte visible -->
<button aria-label="Soumettre le formulaire">Envoyer</button>
→ Commande vocale "cliquer Envoyer" : ne fonctionne pas
→ Commande vocale "cliquer Soumettre le formulaire" : fonctionne

<!-- ✓ Bon : le texte visible est inclus, en début de chaîne -->
<button aria-label="Envoyer le formulaire d'inscription">Envoyer</button>
→ Commande vocale "cliquer Envoyer" : fonctionne

Le texte visible doit apparaître au début de l’aria-label, pas au milieu ou à la fin. Les logiciels de reconnaissance vocale font souvent une correspondance par préfixe.

aria-labelledby : référence le texte d’un autre élément par son id. Plus flexible : peut référencer plusieurs éléments, s’adapte si le texte change dynamiquement.

<!-- Modal dont le titre est le label -->
<div role="dialog" aria-labelledby="titre-modal">
  <h2 id="titre-modal">Confirmer la suppression</h2>
  ...
</div>
→ NVDA : "Confirmer la suppression, boîte de dialogue"

<!-- Label composé de plusieurs éléments -->
<tr>
  <td id="nom-produit">Chaise ergonomique</td>
  <td>
    <input
      type="number"
      aria-labelledby="col-quantite nom-produit"
    >
  </td>
</tr>
<th id="col-quantite">Quantité</th>
→ NVDA : "Quantité Chaise ergonomique, zone de saisie"

aria-describedby : description complémentaire, lue après le nom et le rôle. Ne remplace jamais le nom, il ajoute du contexte.

<input
  type="password"
  id="mdp"
  aria-describedby="regles-mdp"
>
<p id="regles-mdp">
  Au moins 8 caractères, une majuscule, un chiffre.
</p>
→ NVDA : "Mot de passe, zone de saisie, Au moins 8 caractères, une majuscule, un chiffre."

Erreur fréquente : utiliser aria-describedby à la place d’aria-labelledby pour nommer un composant. La description est lue en dernier et peut être ignorée selon les paramètres AT.

Critères RGAA : 6.1 , 6.2 , 11.1 , 11.2 .


aria-controls

Référence l’élément contrôlé par le composant courant, par son id. Utilisé sur les déclencheurs d’accordéon, de menu, d’onglets.

<button aria-expanded="false" aria-controls="panneau-1">
  Voir les tarifs
</button>
<div id="panneau-1" hidden>...</div>

Le support des lecteurs d’écran est très faible. NVDA, VoiceOver et TalkBack n’annoncent rien d’aria-controls dans leurs réglages par défaut. JAWS pouvait l’annoncer sur demande, mais ne le fait plus par défaut dans ses versions récentes. Le développeur Heydon Pickering avait documenté cette limite dès 2016 dans un article resté une référence : aria-controls is poop lien externe qui s'ouvre dans un nouvel onglet . Près e dix ans plus tard, le constat n’a pas changé.

Ce que ça signifie en pratique : ne comptez jamais sur aria-controls pour qu’un utilisateur soit informé d’une relation entre un déclencheur et son contenu. La relation passe par autre chose.

Ce qui marche vraiment. Placez l’élément contrôlé immédiatement après son contrôle dans le DOM. Un panneau d’accordéon doit suivre son bouton, une listbox doit suivre son combobox, un panneau d’onglet doit suivre sa liste d’onglets. La navigation séquentielle au clavier (Tab) et à la voix amène alors naturellement l’utilisateur au contenu, sans avoir besoin d’une annonce ARIA.

Faut-il garder aria-controls malgré tout ? Oui, dans deux cas. Premier cas : quand l’id référencé sert d’autres mécanismes (tests automatiques, CSS, script). Deuxième cas : quand le pattern WAI-ARIA APG le mentionne explicitement (combobox, tablist), pour rester conforme à la documentation officielle. L’attribut documente l’intention sans rien promettre côté annonce.

Critère RGAA : 7.1 .


aria-owns

Déclare une relation de parenté entre un élément et un autre qui n’est pas son enfant dans le DOM. Permet aux AT de comprendre qu’un élément appartient logiquement à un composant, même si le HTML les sépare physiquement.

<!-- Cas d'usage typique : listbox dont les options sont hors du DOM parent -->
<div role="combobox"
     aria-expanded="true"
     aria-owns="liste-suggestions"
     aria-controls="liste-suggestions">
  <input type="text" id="champ-ville">
</div>

<!-- La liste est ailleurs dans le DOM pour des raisons de z-index ou de portail -->
<ul id="liste-suggestions" role="listbox">
  <li role="option">Brest</li>
  <li role="option">Quimper</li>
</ul>
→ NVDA : le combobox et la listbox sont annoncés comme un seul composant
  malgré leur séparation dans le DOM

Mise en garde importante : aria-owns recrée artificiellement une structure que le DOM ne reflète pas. C’est un correctif de dernier recours. Si la structure HTML peut être réorganisée pour que les éléments soient de vrais parents/enfants, c’est toujours préférable. Un DOM logique est plus robuste qu’une relation ARIA.

Support AT : bien supporté par JAWS et NVDA sur les composants qui l’utilisent conformément à l’APG (combobox, tree). Moins fiable sur des usages non documentés.

Ne pas utiliser aria-owns pour : réorganiser visuellement des éléments (c’est le rôle du CSS), compenser un DOM désordonné qui pourrait être corrigé, ou créer des relations circulaires.

Critère RGAA : 7.1 .


aria-flowto

Suggère un ordre de lecture alternatif à l’ordre du DOM. Permet à l’utilisateur AT de suivre un flux logique différent de l’ordre séquentiel des éléments dans le code.

<!-- Mise en page multi-colonnes où l'ordre de lecture logique
     ne suit pas l'ordre du DOM -->
<div id="colonne-1">
  <p id="intro" aria-flowto="suite-intro">
    La commune de Nom_ville est située près de Brest...
  </p>
  <aside>Encadré : chiffres clés</aside>
</div>
<div id="colonne-2">
  <p id="suite-intro">
    ...à la pointe de la Bretagne, face à l'Atlantique.
  </p>
</div>
→ Avec aria-flowto : l'utilisateur peut choisir de sauter
  l'encadré et passer directement à "suite-intro"
→ Sans aria-flowto : l'AT lit l'encadré avant la suite du paragraphe

Réalité du support : aria-flowto est l’attribut le moins bien supporté de cette famille. Peu de lecteurs d’écran l’implémentent et ceux qui le font ne le signalent pas toujours à l’utilisateur. En pratique, ne pas compter sur aria-flowto pour résoudre un problème d’ordre de lecture, corriger l’ordre du DOM est la seule solution fiable.

aria-flowto reste documenté ici car il apparaît dans des audits et des discussions, mais son usage en production est déconseillé faute de support réel.


aria-posinset et aria-setsize

Ces deux attributs fonctionnent ensemble pour indiquer la position d’un élément dans un ensemble et la taille totale de cet ensemble. Ils sont utilisés quand les éléments d’une liste ou d’un groupe sont chargés dynamiquement ou ne sont pas tous présents dans le DOM.

<!-- Liste paginée : 200 résultats, mais seulement 20 affichés -->
<ul role="listbox">
  <li role="option"
      aria-posinset="1"
      aria-setsize="200">
    Résultat 1
  </li>
  <li role="option"
      aria-posinset="2"
      aria-setsize="200">
    Résultat 2
  </li>
  <!-- ... jusqu'au 20e résultat -->
</ul>
→ NVDA : "Résultat 1, 1 sur 200"
  au lieu de : "Résultat 1, 1 sur 20"
  (qui serait trompeur si l'utilisateur ne sait pas qu'il y a plus de résultats)

Quand les utiliser : uniquement quand le DOM ne contient pas tous les éléments de l’ensemble (chargement infini, pagination, virtualisation de liste, etc.). Quand tous les éléments sont dans le DOM, les AT calculent automatiquement la position et la taille, aria-posinset et aria-setsize sont alors inutiles et potentiellement contradictoires.

<!-- ✗ Inutile si tous les éléments sont dans le DOM -->
<li role="option" aria-posinset="1" aria-setsize="5">Premier</li>
<li role="option" aria-posinset="2" aria-setsize="5">Deuxième</li>
<li role="option" aria-posinset="3" aria-setsize="5">Troisième</li>
<!-- ... -->

<!-- ✓ Nécessaire si seulement certains éléments sont chargés -->
<li role="option" aria-posinset="41" aria-setsize="200">Résultat 41</li>

Critère RGAA : 7.1 .


aria-keyshortcuts

Indique un raccourci clavier associé à un élément. L’AT peut annoncer ce raccourci à l’utilisateur pour lui signaler qu’un accès rapide est disponible.

<!-- Bouton de recherche avec raccourci clavier Ctrl+K -->
<button aria-keyshortcuts="Control+K">
  Rechercher
</button>

<!-- Lien d'évitement avec raccourci -->
<a href="#contenu-principal" aria-keyshortcuts="Alt+1">
  Aller au contenu
</a>
→ NVDA : "Rechercher, bouton, raccourci clavier Ctrl+K"

Deux conditions pour utiliser aria-keyshortcuts :

  1. Le raccourci doit réellement fonctionner sur la page, l’attribut documente un raccourci existant, il ne le crée pas.
  2. Le raccourci doit respecter le critère WCAG 2.1.4 (raccourcis clavier à une touche) : si le raccourci utilise une seule touche lettre, chiffre ou signe de ponctuation, il doit être désactivable ou reconfigurable.

Support AT : bien supporté par JAWS et NVDA récents. À utiliser avec parcimonie, multiplier les raccourcis documentés surcharge l’annonce.

Critère RGAA : 7.1 .


aria-live et aria-atomic

aria-live transforme une zone en live region : les changements de contenu sont annoncés automatiquement aux AT.

Valeurs de aria-live :

<!-- polite — attend la fin de la lecture en cours -->
<div aria-live="polite" id="statut-sauvegarde"></div>

<!-- assertive — interrompt la lecture en cours (urgences uniquement) -->
<div aria-live="assertive" id="alerte-erreur"></div>

<!-- off — désactive les annonces (compteur qui se met à jour chaque seconde) -->
<div aria-live="off" role="timer" id="compte-a-rebours"></div>

aria-atomic : contrôle si l’AT annonce le changement partiel ou la zone entière.

<!-- Sans aria-atomic : seul le texte modifié est annoncé -->
<div aria-live="polite">
  Résultats : <span id="nb">0</span> éléments trouvés
</div>
→ Si nb passe à 12 : NVDA annonce "12" seulement

<!-- Avec aria-atomic="true" : toute la zone est relue -->
<div aria-live="polite" aria-atomic="true">
  Résultats : <span id="nb">0</span> éléments trouvés
</div>
→ Si nb passe à 12 : NVDA annonce "Résultats : 12 éléments trouvés"

Bonne pratique : aria-atomic="true" pour les messages de statut courts, aria-atomic="false" (défaut) pour les listes qui s’enrichissent (flux d’activité, chat).

La règle d’injection (rappel crucial) : la zone live doit être dans le DOM avant l’injection du message. Pour forcer la relecture :

const zone = document.getElementById('statut');
zone.textContent = '';
requestAnimationFrame(() => {
  zone.textContent = 'Modifications enregistrées.';
});

Critère RGAA : 7.5 .

Famille 3 : Informations contextuelles

Ces attributs communiquent des informations de contexte : état requis, validité, position dans un parcours.

aria-current

Identifie l’élément courant dans un ensemble : page active, étape en cours, date sélectionnée.

Valeurs et usages :

<!-- Navigation — page active -->
<nav aria-label="Navigation principale">
  <ul>
    <li><a href="/" aria-current="page">Accueil</a></li>
    <li><a href="/contact">Contact</a></li>
  </ul>
</nav>
→ NVDA : "Accueil, page actuelle, lien"

<!-- Fil d'Ariane — position actuelle -->
<nav aria-label="Fil d'Ariane">
  <ol>
    <li><a href="/">Accueil</a></li>
    <li><a href="/mairie">Mairie</a></li>
    <li><span aria-current="page">Horaires</span></li>
  </ol>
</nav>

<!-- Formulaire multi-étapes — étape en cours -->
<ol class="etapes">
  <li><span aria-current="step">Vos coordonnées</span></li>
  <li>Récapitulatif</li>
  <li>Confirmation</li>
</ol>

<!-- Calendrier — date sélectionnée -->
<td aria-current="date">14</td>

<!-- Contexte générique -->
<li aria-current="true">Élément actif</li>

Piège WordPress : certains thèmes ajoutent une classe CSS .current-menu-item sur le lien actif, mais n’ajoutent pas toujours aria-current="page". L’état actif est visible visuellement (couleur différente) mais invisible aux AT. À corriger dans le template de navigation ou via un filtre PHP :

// Dans functions.php
add_filter('nav_menu_link_attributes', function($atts, $item) {
    if (in_array('current-menu-item', $item->classes)) {
        $atts['aria-current'] = 'page';
    }
    return $atts;
}, 10, 2);

Critères RGAA : 12.2 (navigation cohérente), 12.3 (plan du site).


aria-required

Indique qu’un champ de formulaire est obligatoire. Complète l’attribut HTML required : les deux peuvent coexister.

required (HTML)aria-required="true" (ARIA)
Validation native navigateurOuiNon
Annoncé par les ATOuiOui
Bloque la soumissionOuiNon
Applicable aux composants customNonOui
<!-- Champ natif — required suffit -->
<label for="email">
  Adresse email <span aria-hidden="true">*</span>
</label>
<input type="email" id="email" required>

<!-- Composant custom — aria-required obligatoire -->
<div role="combobox" aria-required="true" aria-label="Département">
  ...
</div>

La mention visuelle de l’obligatoire (* ou “obligatoire”) doit toujours être expliquée en début de formulaire :

<p>Les champs marqués d'un <span aria-hidden="true">*</span>
<span class="sr-only">astérisque</span> sont obligatoires.</p>

Critère RGAA : 11.9 , 11.10 .


aria-invalid et aria-errormessage

aria-invalid signale qu’un champ contient une valeur incorrecte. aria-errormessage référence le message d’erreur associé.

Valeurs d’aria-invalid :

  • "true" : valeur incorrecte (générique)
  • "false" : valeur correcte (défaut, peut être omis)
  • "grammar" : erreur grammaticale
  • "spelling" : erreur orthographique
<!-- Champ en erreur avec message associé -->
<label for="code-postal">Code postal</label>
<input
  type="text"
  id="code-postal"
  aria-invalid="true"
  aria-errormessage="erreur-cp"
  aria-describedby="aide-cp"
  value="123"
>
<p id="aide-cp">Format attendu : 5 chiffres (ex. 29770)</p>
<p id="erreur-cp" role="alert">
  Le code postal doit contenir exactement 5 chiffres.
</p>
→ NVDA au focus : "Code postal, zone de saisie, invalide, Format attendu : 5 chiffres"
→ NVDA (role=alert annonce immédiatement) : "Le code postal doit contenir exactement 5 chiffres."

Ordre des opérations à la soumission :

function validerFormulaire() {
  const input = document.getElementById('code-postal');
  const erreur = document.getElementById('erreur-cp');

  if (!/^\d{5}$/.test(input.value)) {
    // 1. Marquer le champ invalide
    input.setAttribute('aria-invalid', 'true');
    // 2. Afficher et remplir le message d'erreur (live region)
    erreur.textContent = 'Le code postal doit contenir exactement 5 chiffres.';
    // 3. Déplacer le focus sur le champ en erreur
    input.focus();
  } else {
    input.setAttribute('aria-invalid', 'false');
    erreur.textContent = '';
  }
}

Critères RGAA : 11.10 , 11.11 .


aria-haspopup

Indique qu’un élément déclenche l’ouverture d’un composant overlay. Prépare l’utilisateur AT à ce qui va s’ouvrir.

Valeurs et composants associés :

ValeurComposant qui s’ouvreAnnonce NVDA
"true" ou "menu"role="menu"”sous-menu”
"listbox"role="listbox"”zone de liste”
"tree"role="tree"”arborescence”
"grid"role="grid"”grille”
"dialog"role="dialog"”boîte de dialogue”
<!-- Bouton qui ouvre un menu d'actions -->
<button aria-haspopup="menu" aria-expanded="false" aria-controls="menu-actions">
  Actions
</button>
<ul role="menu" id="menu-actions" hidden>
  <li role="menuitem">Modifier</li>
  <li role="menuitem">Supprimer</li>
</ul>
→ NVDA : "Actions, bouton sous-menu, réduit"

<!-- Bouton qui ouvre une modale -->
<button aria-haspopup="dialog">
  Voir les détails
</button>
→ NVDA : "Voir les détails, bouton boîte de dialogue"

Erreur fréquente : utiliser aria-haspopup="true" pour tout type de popup. La valeur "true" implique spécifiquement un role="menu", pas une modale, pas une listbox. Utiliser la valeur spécifique au composant qui s’ouvre.

Critère RGAA : 7.1 .


Tableau de décision rapide

SituationAttribut à utiliser
Nommer un bouton icônearia-label
Lier un titre à une regionaria-labelledby
Ajouter une description d’aidearia-describedby
Accordéon ouvert/ferméaria-expanded
Onglet sélectionnéaria-selected
Case cochée/décochéearia-checked
Bouton toggle actif/inactifaria-pressed
Élément désactivé mais focusablearia-disabled
Icône décorativearia-hidden="true"
Lien de la page activearia-current="page"
Étape active dans un tunnelaria-current="step"
Champ obligatoire (custom)aria-required="true"
Champ en erreuraria-invalid="true" + aria-errormessage
Bouton qui ouvre une modalearia-haspopup="dialog"
Message de confirmationaria-live="polite"
Message d’erreur urgentaria-live="assertive" ou role="alert"
Élément hors DOM appartenant à un composantaria-owns
Position dans une liste chargée partiellementaria-posinset + aria-setsize
Raccourci clavier associé à un élémentaria-keyshortcuts

Pour aller plus loin

La lettre de l'Atelier A11Y

Ressources pédagogiques, critères RGAA commentés et retours de terrain : une lettre mensuelle pour progresser sur l'accessibilité numérique, sans jargon.

  • Nouveaux articles et ressources pédagogiques
  • Critères RGAA décortiqués avec des exemples concrets
  • Bonnes pratiques et retours d'expérience terrain
S'abonner à la newsletter (s'ouvre dans un nouvel onglet)

Gratuit. Désabonnement possible à tout moment.