Bouton de rôle ARIA : Guide complet et pratique
Le rôle ARIA button est un rôle ARIA qui fait que les technologies d’assistance annoncent un conteneur générique comme le bouton, mais n’apporte aucun comportement : il faut ajouter tabindex="0", gérer Enter et Espace, et refléter l’état avec aria-pressed ou aria-disabled. La spécification WAI-ARIA 1.2 définit ce rôle dans la catégorie du widget, et la première règle d’ARIA recommande d’utiliser un <bouton> natif si possible.
Le rôle ARIA button appartient à la taxonomie des rôles de WAI-ARIA, la norme du W3C qui décrit la sémantique accessible aux interfaces Web. Lorsqu’un élément reçoit role="button", l’arbre d’accessibilité qui construit les lecteurs d’écran (NVDA, JAWS, VoiceOver, Narrator) cesse de l’exposer comme un div ou un span générique et le présente comme un contrôle accessible. La différence est énorme pour qui navigue avec le lecteur d’écran : sans le rôle, l’utilisateur entend “groupe” ou simplement texte ; avec le rôle, vous avez un « bouton » et vous savez que vous pouvez l’activer.
La confusion habituelle est que role="button" convertit un div en un bouton fonctionnel. Ce n’est pas le cas. Le rôle seul change la sémantique annoncée ; le comportement — recevoir le focus, répondre au clavier, déclencher l’action — reste la responsabilité du développeur. Cette séparation entre la sémantique et le comportement est la raison de la plupart des erreurs qui se produisent avec ce rôle.
WAI-ARIA est publié comme recommandation du W3C et sa version 1.2 est la référence actuelle pour les rôles, les états et les propriétaires. Le rôle « bouton » est l’un des rôles de widget les plus anciens et stables de la spécification, présents depuis ARIA 1.0.
Quand utiliser role=“button” et quand ne pas le faire
La première règle d’ARIA, reconnue dans les pratiques d’auteur de WAI-ARIA (WAI-ARIA Authoring Practices), est la suivante : s’il existe un élément HTML natif avec la sémantique et le comportement qui est nécessaire, utilisez-le. <bouton> vous indique implicitement le rôle, le focus clavier, l’activation avec Entrée et Espace, et l’état est désactivé. Réimplémenter tout cela avec le rôle role="button" est un travail supplémentaire et source de bugs.
Existent, cependant, des scénarios légitimes pour le rôle. La plupart du temps, c’est lorsque le balisage est conditionné par le framework ou le CMS et qu’il n’est pas possible d’introduire un <bouton> sans rompre la mise en page ou le JavaScript existant. Dans un autre cas, ce sont les composants qui doivent se comporter comme un bouton mais dont la structure interne exige un conteneur spécifique, comme de nombreux widgets de troisièmes.
Connexes : — Widget d'accessibilité avec plan gratuit pour gagner aujourd'hui.
Un troisième scénario, le plus discutable, est l’élément qui vous donne un rôle naturel distinct et doit être présenté comme bouton. Ici, vous devriez vous attendre à ce que le design ne soit pas une sémantique équivoque. Si quelque chose ressemble à un bouton mais dans la réalité de la navigation sur une autre page, le correct est un lien <a>, pas un bouton.
| Situation | Solution recommandée | Motif |
|---|---|---|
| Action sur le formulaire ou l’interface | <bouton> naturel | Rôle, foyer et clavier inclus |
| Navigation vers une autre URL | <a href> | Sémantique de lien correcte |
| Conteneur non modifiable | role="button" + clavier + états | Cas unique où le rôle est porté |
| Bouton d’alternance (on/off) | <bouton aria-pressé> | Estado expuesto nativamente |
| Bouton désactivé | <bouton désactivé> | État et fonctions gérées |
Comment implémenter correctement un bouton avec role=“button”
Un bouton basé sur role="button" nécessite d’avoir quatre façades : champ, clavier, état et nombre accessibles. Omettre l’un d’entre eux produit un contrôle qui “semble” accessible mais échoue aux tests réels.
Le focus est habilité avec tabindex="0", qui insère l’élément dans l’ordre de tabulation naturel. Nunca utilise tabindex avec des valeurs positives : modifier l’ordre de tabulation de toute la page et générer des sauts imprédécibles. La valeur « 0 » est la bonne pour les éléments interactifs personnalisés.
Ça vaut le coup d'oeil : — Accessibilité gérée : automatisation combinée avec révision humaine.
Le clavier nécessite la gestion de deux touches : Entrée et Espace. Un <bouton> répond naturellement aux ambas, mais un div avec un air de bouton ne le fait pas pour vous seul. Vous devez écouter « keydown » et exécuter l’action lorsque la touche est « Enter » ou « Space », en évitant également le défilement de la page provoqué par la touche Espace par défaut. Ces détails est souvent négligé et laisse des boutons qui ne fonctionnent qu’avec la souris.
L’état est communiqué avec les attributs ARIA. Un bouton d’alternance utilise aria-pressed="true" ou "false" pour indiquer si il est actif. Un bouton désactivé utilise aria-disabled="true", qui annonce l’état mais n’empêche pas l’interaction si vous êtes seul : il bloque l’action dans le code. La différence entre « aria-disabled » et l’attribut natif « disabled » est importante, car le premier maintient l’élément focusable et le second le retire de l’ordre de tabulation.
Le nom accessible est construit avec le texte visible de l’élément ou, s’il n’y a pas de texte, avec aria-label ou aria-labelledby. Un bouton sans nom accessible est un bouton que le lecteur de l’écran annonce comme « bouton » à quelques secondes, sans piste de ce qu’il fait.
<div
role="button"
tabindex="0"
aria-pressed="false"
id = "btn-modo"
>
Mode obscur
</div>
<script>
const btn = document.getElementById('btn-modo');
function toggle() {
const activé = btn.getAttribute('aria-pressed') === 'true';
btn.setAttribute('aria-pressed', String(!activo));
}
btn.addEventListener('cliquez', bascule);
btn.addEventListener('keydown', (e) => {
if (e.key === 'Entrée' || e.key === ' ') {
e.preventDefault();
toggle();
}
});
</script>
L’exemple précédent couvre le focus, le clavier, l’état et le nom. C’est le minimum viable pour que le contrôle soit utilisable avec le lecteur d’écran et le clavier.
Erreurs fréquentes et comment les détecter
L’erreur la plus étendue est appliquée à role="button" sans tabindex, ce qui produit un bouton inalcanzable pour le clavier. Les outils automatiques le détectent comme “un élément de rôle interactif non applicable”, l’une des violations les plus signalées dans les auditoires d’accessibilité.
La deuxième erreur n’est pas gérée par le clavier. Un div avec un air de bouton et tabindex mais sans que les opérateurs de clavier ne reçoivent une réponse et ne répondent pas à Enter ni Espacio. L’utilisateur du clavier qui est bloqué : peut appuyer sur le bouton mais ne pas l’activer.
Connexes : — La qui accrédite votre expérience en accessibilité.
La troisième erreur est d’utiliser role="button" sur un lien. Cela perturbe la sémantique de navigation et confond les lecteurs d’écran, qui annoncent le « bouton » lorsque l’utilisateur espère un lien. Si l’élément navega, il doit être un enlacé.
Le coin de l’erreur est effacé de l’état sur les boutons d’alternance. Un bouton qui change entre deux modes sans « aria-pressed » est déjà l’utilisateur sans savoir ce qui se passe. L’attribut est la forme unique de communication et est adopté comme forme programmatique.
Pour détecter ces problèmes, les outils automatiques tels que Lighthouse ou WAVE signalent les violations du rôle et de la direction, mais ne valident pas le comportement du clavier ni la logique de l’état. Cette partie nécessite de vérifier le manuel : naviguer avec Tab, activer avec Enter et Espacio, et ouvrir la sortie du lecteur d’écran. La combinaison de l’auditeur automatique et du manuel d’essai est la seule forme fiable de valider un bouton personnalisé.
Comment tester un bouton avec role=“button”
La vérification s’effectue par le clavier. Enregistrez la page avec l’onglet et vérifiez que le bouton avec le bouton de rôle aria reçoit la position visible. Appuyez sur Entrée et sur l’espace séparé : vous devrez alors disparaitre de l’action. Si l’espace apparaît sur la page à l’endroit où activer le bouton, cliquez sur « preventDefault ».
La deuxième vérification est effectuée avec le lecteur d’écran. NVDA sur Windows, VoiceOver sur macOS et Narrator sur Windows sont les références les plus utilisées. En appuyant sur le bouton, le lecteur doit annoncer le rôle (« bouton »), le nombre accessible et l’état si vous l’avez. Si vous annoncez “grupo” ou ne mentionnez pas l’état, quelque chose est tombé.
La troisième évaluation est de l’ordre du foyer. Le bouton doit apparaître dans l’ordre logique de tabulation, ni avant ni après que la pièce ne corresponde visuellement. Les tabindex positifs rompent cet ordre et sont un indicateur clair de mauvaise mise en œuvre.
La zone d’essai est de contraste et de lumière visible. L’indicateur de foco ne doit pas être éliminé avec « contour : aucun » sans le remplacer par une alternative visible. Un bouton qui reçoit votre attention mais qui ne devrait pas être celui de l’utilisateur du clavier sans référence de là.
Bouton Alternatives modernes au rôle
L’élément <bouton> naturel reste la meilleure option en 2024 et dans tout nouveau projet. Portez le rôle, la direction, le clavier et l’état sans code supplémentaire, et les navigateurs le feront de manière cohérente.
Les éléments personnalisés ou les composants Web disponibles ailleurs. Un composant qui étend HTMLElement peut encapsuler le comportement du bouton et l’exposer avec la sémantique correcte, mais nécessite également de gérer manuellement le focus et le clavier comme avec role="button". La vente est la réutilisation ; la desventaja, la même responsabilité de mise en œuvre.
Las ARIA in HTML (règles qui définissent les rôles ARIA se permettent sur chaque élément HTML) desaconsejan pour écrire des rôles nationaux. Appliquer le rôle aria role="button" à un <button> est redondant ; appliquer à un <a> avec href est contreproductif. La recommandation générale est de réserver le rôle des conteneurs sans propriété sémantique.
Points clés à retenir
role="button"modifie uniquement la signification sémantique ; le foco, le clavier et l’état sont à mettre en œuvre à la main.- La première règle d’ARIA recommande d’utiliser
<bouton>localement toujours que le marqueur le permet. - Un bouton avec le bouton de rôle aria nécessite
tabindex="0", la touche Enter et l’espace, le nombre accessible et l’état avecaria-pressedouaria-disabled. - Les outils automatiques détectent le manque de foco, mais le comportement du clavier et l’état exige une vérification manuelle avec le lecteur d’écran.
- Nunca utilise
tabindexpositif ni apliquerole="button"pour enlacer ce n’est pas nécessaire.
Questions fréquemment posées
Quelle est la différence entre role=“button” et l’élément bouton ?
L’élément <bouton> naturel inclut le rôle implicite, la touche du clavier, l’activation avec Entrée et Espace et l’état désactivé sans code supplémentaire. L’attribut role="button" apporte uniquement la signification sémantique ; le reste du comportement doit être programmé. C’est pourquoi la première règle d’ARIA recommande l’élément naturel toujours possible.
Vous avez besoin d’un tabindex avec role=“button” ?
Si. Un div ou span avec role="button" n’est pas applicable par défaut, de même que tabindex="0" est hors de l’ordre de tabulation et est inutilisable avec le clavier. La valeur correcte est « 0 » ; les valeurs positives modifient l’ordre de tabulation de toute la page et doivent être évitées.
Comment un div avec role=“button” répond-il à Enter et à l’espace ?
Vous devez écouter l’événement keydown et exécuter l’action lorsque la touche est Enter ou Space. Dans le cas de l’Espace, vous pouvez appeler « preventDefault » pour éviter la suppression de la page. Sans ces manœuvreurs, le bouton reçoit la réponse mais ne s’active pas avec le clavier.
Comment indiquer qu’un bouton est activé ou désactivé ?
Pour un bouton d’alternance, utilisez aria-pressed="true" ou "false" selon l’état. Pour un bouton désactivé, utilisez aria-disabled="true", qui annonce l’état mais ne bloque pas l’interaction si vous êtes seul : cela empêche l’action dans le code. L’attribut natif disabled est préférable si vous utilisez un <bouton>.
Est-ce une mauvaise pratique d’utiliser role=“button” dans un lien ?
Oui, lorsque vous enlacez le navigateur vers une autre URL. Écrire le rôle d’un <a href> avec role="button" rompt la sémantique de navigation et confond les lecteurs d’écran, qui annoncent le “bouton” lorsque l’utilisateur espère un lien. Si l’élément navega, vous devez conserver votre rôle d’enlacement.
¿Qué des outils détectent-ils des erreurs avec role=“button” ?
Des outils automatiques comme axe, Lighthouse ou WAVE signalent des violations comme la faute de feu dans les éléments avec rôle interactif. Cependant, le comportement du clavier et la logique de l’état ne sont pas validés, ainsi que la vérification fiable combinée à un auditoire automatique avec un test manuel en utilisant NVDA, VoiceOver ou Narrateur.
Questions fréquentes
Quelle est la différence entre role='button' et l'élément bouton ?
L'élément <bouton> natif inclut le rôle implicite, le champ de clavier, l'activation avec Enter et l'espace et l'état désactivé sans code supplémentaire. L'attribut role='button' affiche uniquement la signification sémantique ; le reste du comportement doit être programmé. C'est pourquoi la première règle d'ARIA recommande l'élément naturel toujours possible.
Avez-vous besoin de tabindex avec role='button' ?
Si. Un div ou un span avec role='button' n'est pas applicable par défaut, de même que tabindex='0' qui est hors de l'ordre de tabulation et est inutilisable avec le clavier. La valeur correcte est 0 ; les valeurs positives modifient l’ordre de tabulation de toute la page et doivent être évitées.
Comment se fait-il qu'un div avec role='button' réponde à Enter et à l'espace ?
Vous devez écouter l'événement enfoncé et exécuter l'action lorsque la touche est Enter ou Space. Dans le cas d'Espacio, vous pouvez appeler à PreventDefault pour éviter la suppression de la page. Sans ces manœuvreurs, le bouton reçoit la réponse mais ne s'active pas avec le clavier.
Comment indiquer qu'un bouton est activé ou désactivé ?
Pour un bouton d'alternance, utilisez aria-pressed='true' ou 'false' selon l'état. Pour un bouton désactivé, utilisez aria-disabled='true', qui annonce l'état mais ne bloque pas l'interaction si vous êtes seul : cela empêche l'action dans le code. L'attribut natif désactivé est préférable si vous utilisez un <bouton>.
Est-ce une mauvaise pratique d'utiliser role='button' sur un lien ?
Oui, lorsque vous enlacez le navigateur vers une autre URL. Écrivez le rôle d'un <a href> avec role='button' en rompant la sémantique de navigation et en confondant les lecteurs d'écran, en annonçant le « bouton » lorsque l'utilisateur espère un lien. Si l’élément navega, vous devez conserver votre rôle d’enlacement.
Pourquoi les outils détectent-ils les erreurs avec role='button' ?
Des outils automatiques comme axe, Lighthouse ou WAVE signalent des violations comme la faute de feu dans les éléments avec rôle interactif. Cependant, le comportement du clavier et la logique de l'état ne sont pas validés, ainsi que la vérification fiable combinée à un auditoire automatique avec un test manuel en utilisant NVDA, VoiceOver ou Narrateur.
Comment utiliser les WCAG sans consulter le code ?
Superposición de IA qui promet d’obtenir les WCAG dans 48 heures