Chapitre 6.2 — Les rôles
⏱️ TL;DR — Un rôle ARIA déclare ce qu’est un élément pour le lecteur d’écran. On les range en quatre familles : landmark (régions de page), widget (composants interactifs), structure (organisation du contenu) et live region (zones qui s’annoncent seules). Point capital : un
rolesurcharge la sémantique native. Poserrole="button"sur un<h2>et ce n’est plus un titre. Le meilleur rôle, c’est souvent celui que tu n’écris pas — parce que l’élément natif le porte déjà.
🎯 Objectifs
- Nommer les quatre catégories de rôles ARIA et donner un exemple de chacune.
- Comprendre que le
roleécrase le rôle natif de l’élément. - Distinguer un rôle utile d’un rôle redondant ou dangereux.
- Savoir à quoi servent
role="presentation"etrole="none".
Les quatre catégories de rôles
ARIA définit des dizaines de rôles, mais tous tombent dans quatre grandes familles.
1. Landmark (régions)
Ils découpent la page en régions navigables par le lecteur d’écran : banner, navigation, main, complementary, contentinfo, search, form, region. La plupart ont un équivalent natif à préférer : <header> → banner, <nav> → navigation, <main> → main, <aside> → complementary, <footer> → contentinfo. On n’écrit role="search" que faute de balise dédiée.
2. Widget (composants interactifs)
Le vocabulaire des composants riches : button, checkbox, radio, tab, tablist, tabpanel, dialog, menu, menuitem, slider, switch, combobox, tree… C’est ici qu’ARIA est irremplaçable quand il n’existe pas de balise native — mais chaque rôle de widget t’engage à coder le clavier et les états (voir 6.1).
3. Structure (organisation)
Ils décrivent l’organisation du contenu : heading, list, listitem, table, row, cell, article, group, presentation / none. Là encore, <h1>, <ul>, <table> les portent nativement — on ne les écrit qu’exceptionnellement.
4. Live region (zones qui s’annoncent)
Des zones dont le changement de contenu est annoncé sans déplacer le focus : status, alert, log, progressbar, timer, marquee. On y consacre tout le chapitre 6.4.
Le rôle surcharge la sémantique native
C’est la notion à retenir. L’attribut role ne s’ajoute pas au rôle natif : il le remplace. L’élément conserve son apparence et son comportement HTML, mais dans l’arbre d’accessibilité, il devient uniquement ce que le role dit.
<!-- ❌ Ce n'est PLUS un titre pour le lecteur d'écran -->
<h2 role="button">Section Paramètres</h2>Ici, l’utilisateur qui navigue par titres (une manière très courante d’explorer une page) ne trouvera jamais « Section Paramètres » : le role="button" a effacé le rôle « titre niveau 2 ». Tu as cassé la navigation pour un gain nul. Si tu veux un titre cliquable, mets un <button> à l’intérieur du titre :
<!-- ✅ Le titre reste un titre ; le bouton est un vrai bouton -->
<h2>
<button type="button" aria-expanded="false" aria-controls="params">
Section Paramètres
</button>
</h2>⚠️ Piège — Écraser un rôle natif. Chaque fois que tu écris
role="X"sur un élément qui a déjà un rôle utile (<h2>,<a>,<li>,<nav>…), tu détruis ce rôle. Les cas les plus destructeurs :rolesur un titre (navigation par titres perdue), sur un<a href>(le lien n’est plus annoncé « lien »), sur un<li>isolé (la liste se disloque). Demande-toi toujours : qu’est-ce que j’efface en écrivant ça ?
Rôles utiles vs rôles redondants
Un rôle est utile quand il apporte une sémantique que le HTML n’a pas. Il est redondant — donc à supprimer — quand il répète le rôle natif.
<!-- ❌ Redondant : le <button> a déjà le rôle « button » -->
<button role="button">Envoyer</button>
<!-- ❌ Redondant : le <nav> a déjà le rôle « navigation » -->
<nav role="navigation">…</nav>
<!-- ❌ Redondant et fragile : réinventer une liste -->
<ul role="list"><li role="listitem">…</li></ul>
<!-- ✅ Utile : aucune balise native pour un système d'onglets -->
<div role="tablist">
<button role="tab" aria-selected="true">Mes cours</button>
<button role="tab" aria-selected="false">Terminés</button>
</div>Un rôle redondant n’est pas dramatique en soi, mais c’est du bruit qui masque les vrais besoins et trahit une mauvaise compréhension d’ARIA. Le bon rôle, c’est souvent pas de rôle : laisse la balise native parler.
💡 Réflexe — Avant d’écrire un
role, nomme d’abord la balise native équivalente. Si elle existe (button,nav,ul,table…), utilise-la et supprime lerole. Tu ne gardes leroleque lorsqu’aucune balise ne porte cette sémantique.
role="presentation" et role="none"
Ces deux rôles sont synonymes : ils retirent la sémantique d’un élément, le rendant « transparent » pour le lecteur d’écran (l’élément et ses attributs de rôle disparaissent de l’arbre, mais son contenu reste lu). Usage typique : une <table> employée pour la mise en page (mauvaise pratique héritée) qu’on ne veut pas voir annoncée « tableau, 3 colonnes ».
<!-- Une table de mise en page qu'on neutralise (à éviter, mais si tu en hérites) -->
<table role="presentation">
<tr><td>Logo</td><td>Menu</td></tr>
</table>Attention à la règle n°4 : ne pose jamais role="presentation" (ni aria-hidden) sur un élément focusable ou interactif — tu créerais un fantôme atteignable au clavier mais muet.
Tableau de rôles courants
| Rôle | Catégorie | Équivalent natif à préférer | Quand l’écrire quand même |
|---|---|---|---|
button | widget | <button> | Presque jamais (natif meilleur) |
navigation | landmark | <nav> | Jamais si <nav> dispo |
main | landmark | <main> | Jamais si <main> dispo |
search | landmark | (aucun) | Autour d’un champ de recherche |
dialog | widget | <dialog> | Si <dialog> non utilisable |
tablist / tab / tabpanel | widget | (aucun) | Système d’onglets |
alert | live region | (aucun) | Message d’erreur urgent |
status | live region | (aucun) | Confirmation discrète |
presentation / none | structure | (retire la sémantique) | Neutraliser une table de layout |
🧭 Sur A11yLearn — Sur le tableau de bord d’A11yLearn, on a d’abord vu un dév poser
role="navigation"sur la barre latérale… qui était déjà un<nav>. Redondant : supprimé. En revanche, le filtre « Mes cours / Terminés / Favoris » n’a aucun équivalent HTML : on assumerole="tablist"+role="tab"+aria-selected, et on code la navigation aux flèches. Règle maison : unrolepar écran doit se justifier par l’absence de balise native.
📚 Aller plus loin — La liste complète des rôles est dans la spec WAI-ARIA (
w3.org/TR/wai-aria). Le RGAA et le critère WCAG 4.1.2 exigent que le rôle exposé corresponde à la fonction réelle du composant. Pour choisir le bon rôle d’un widget, pars toujours du pattern correspondant dans l’APG — voir Partie 10.
✏️ Exercices
Exercice 1 — Qu’est-ce qui casse ? Explique ce que ce code fait perdre à un utilisateur de lecteur d’écran.
<a href="/profil" role="button">Mon profil</a>✅ Solution
Le role="button" écrase le rôle natif « lien ». L’utilisateur entend « Mon profil, bouton », alors que c’est un lien de navigation. Conséquences : il ne le trouvera pas dans la liste des liens (raccourci fréquent des lecteurs d’écran), et il s’attend à une action (Espace) alors que c’est une navigation (Entrée, nouvel onglet possible…). Correctif : supprime le role. Un <a href> est déjà annoncé « lien » et fait exactement ce qu’il faut.
Exercice 2 — Titre cliquable. On veut un titre de section qui déplie/replie un panneau. Écris le balisage correct sans casser la navigation par titres.
✅ Solution
On garde le <h2> comme titre et on met un vrai <button> à l’intérieur :
<h2>
<button type="button" aria-expanded="false" aria-controls="panneau-1">
Détails de la commande
</button>
</h2>
<div id="panneau-1" hidden>…</div>Le titre reste annoncé « titre niveau 2 » (navigation par titres intacte) et le bouton porte le clavier, le focus et l’état aria-expanded. On ne surcharge jamais le <h2> lui-même.
🧠 Quiz de révision
1. Quelles sont les quatre catégories de rôles ARIA ?
Landmark (régions de page : navigation, main…), widget (composants interactifs : button, tab, dialog…), structure (organisation : heading, list, presentation…) et live region (zones qui s’annoncent : status, alert…).
2. Que se passe-t-il quand on met role sur un élément qui a déjà un rôle natif ?
role sur un élément qui a déjà un rôle natif ?Le role surcharge (remplace) le rôle natif. <h2 role="button"> n’est plus un titre : il disparaît de la navigation par titres. On efface une sémantique utile pour un gain le plus souvent nul.
3. Pourquoi <button role="button"> est-il à corriger ?
<button role="button"> est-il à corriger ?Parce que le rôle est redondant : le <button> porte déjà le rôle « button ». C’est du bruit qui trahit une mauvaise compréhension d’ARIA. On supprime le role et on laisse la balise native parler.
4. À quoi servent role="presentation" et role="none" ?
role="presentation" et role="none" ?Ce sont des synonymes qui retirent la sémantique d’un élément (il devient transparent pour le lecteur d’écran, mais son contenu reste lu). Usage typique : neutraliser une <table> de mise en page. Interdit sur un élément focusable/interactif.
5. Comment rendre un titre cliquable sans casser la navigation par titres ?
On imbrique un <button> dans le <h2> au lieu de mettre role="button" sur le titre. Le titre reste un titre, le bouton reste un bouton avec son clavier et son aria-expanded.
Chapitre suivant : États & propriétés — ce qui change dans le temps, et comment le tenir à jour en JS.