button
Marque un élément comme bouton — un contrôle qui déclenche une action à l'activation. Préférez toujours l'élément natif <button> ; n'utilisez role="button" sur un <div> ou <span> que lorsque l'élément natif est impossible.
Quand l’utiliser
Presque jamais — utilisez l’élément natif <button>. L’élément natif gère gratuitement le focus, l’activation par les touches Espace et Entrée, l’état désactivé et la sémantique de soumission de formulaire. Recourir à role="button" sur un <div> signifie devoir réimplémenter tout cela, et la plupart des auteurs ne le font pas correctement.
Les cas légitimes pour role="button" sont restreints :
- Vous êtes contraint par un système de design tiers qui livre des composants sans
<button>. - Vous rédigez dans un environnement où
<button>n’est pas disponible (certains gabarits CMS anciens). - Vous améliorez un
<div>pour l’accessibilité à court terme, en attendant une refactorisation.
Si vous utilisez role="button", vous devez également :
- Rendre l’élément focalisable avec
tabindex="0". - Câbler
keydownpourEnteretSpace(avecevent.preventDefault()sur Space pour éviter le défilement de la page). - Gérer vous-même l’état désactivé via
aria-disabled="true"et empêcher les gestionnaires de clic de se déclencher.
Boutons bascule
Si le bouton est un bascule (muet / sonore, lecture / pause, suivre / ne plus suivre), définissez aria-pressed à "true" ou "false". Les lecteurs d’écran annoncent l’état avec le libellé : « Muet, bouton bascule, non activé ».
Erreurs fréquentes
<div onclick="…">Envoyer</div>— non focalisable, inutilisable au clavier, sans rôle. Les utilisateurs de souris peuvent s’en servir ; personne d’autre ne peut.<a href="#" onclick="…">faisant passer un lien pour un bouton. Le navigateur le traite comme un lien, le lecteur d’écran l’annonce comme un lien, l’utilisateur s’attend à une navigation.role="button"sanstabindex="0"— le lecteur d’écran annonce « bouton » mais le clavier ne peut pas l’atteindre.- Des boutons personnalisés qui répondent à Entrée mais pas à Espace.
- Des boutons sans nom accessible — les boutons icône seuls dépourvus de
aria-labelconstituent l’erreur la plus fréquente qu’axe-core détecte.
Exemple
<!-- Préféré -->
<button type="button" aria-pressed="false">Mute</button>
<!-- Uniquement quand <button> est impossible -->
<div
role="button"
tabindex="0"
aria-pressed="false"
onclick="toggleMute()"
onkeydown="if (event.key === 'Enter' || event.key === ' ') { event.preventDefault(); toggleMute(); }"
>
Mute
</div>