ARIA : le rôle button
Le rôle button devrait être utilisé pour les éléments cliquables qui déclenchent une réponse lorsqu'activés par l'utilisateur. Ajouter role="button"
permettra à un élément d'apparaître comme un bouton de contrôle pour un lecteur d'écran. Ce rôle peut être utilisé avec l'attribut aria-pressed
afin de créer des boutons interrupteurs.
<div id="saveChanges" tabindex="0" role="button" aria-pressed="false">
Enregistrer
</div>
L'exemple précédent crée un bouton simple qui sera le premier à obtenir le focus. Toutefois, on devrait plutôt utiliser les éléments <button>
ou <input>
avec type="button"
pour représenter des boutons :
<button id="saveChanges">Enregistrer</button>
Note :
Si on utilise role="button"
plutôt que les éléments sémantiques <button>
ou <input type="button">
, il faudra : permettre à l'élément de recevoir le focus, définir des gestionnaires d'évènements pour click
et keydown
, y compris la gestion des touches Entrée et Espace, afin de traiter la saisie de l'utilisateur. Voir l'exemple de code officiel de WAI-ARIA.
Description
Le rôle button
identifie un élément comme étant un bouton pour les lecteurs d'écran. Un bouton est un contrôle graphique qui permet d'effectuer des actions comme soumettre un formulaire, ouvrir une boîte de dialogue, annuler une action ou effectuer une commande (par exemple ajouter un nouvel enregistrement ou afficher des informations).
Pour indiquer qu'un bouton déclenchera l'ouverture d'une boîte de dialogue, on pourra utiliser la convention qui consiste à ajouter une ellipse (…) après l'étiquette du bouton, par exemple : "Enregistrer sous…".
En complément role="button"
devrait également être utilisé pour les interrupteurs ou les menus qui n'utilisent pas l'élément HTML <button>
. Un interrupteur est un bouton à deux états qui peut être éteint ou actif. Les valeurs de l'attribut aria-pressed
: true
ou false
permettront d'identifier un bouton comme étant un interrupteur. Un bouton de menu permet, comme son nom l'indique, de contrôler un menu et possède un attribut aria-haspopup
qui vaut menu
ou true
.
Rôles, propriétés et états ARIA associés
aria-pressed
-
Définit le bouton comme étant un interrupteur. La valeur de
aria-pressed
décrit l'état du bouton. Les valeurs utilisables incluentaria-pressed="false"
pour indiquer qu'un bouton n'est pas pressé,aria-pressed="true"
pour indiquer qu'un bouton est pressé etaria-pressed="mixed"
pour indiquer que le bouton est partiellement pressé. Si cet attribut est omis ou qu'il utilise la valeur par défautaria-pressed="undefined"
, on ne pourra pas appuyer sur l'élément. aria-expanded
-
Si le bouton contrôle un groupe d'autres éléments, l'état
aria-expanded
indique si le groupe contrôlé est développé ou replié. Si le bouton aaria-expanded="false"
, le groupe n'est pas développé ; si le bouton aaria-expanded="true"
, cela indique qu'il est actuellement développé ; si le bouton aaria-expanded="undefined"
ou que l'attribut est absent, cela indique que le groupe ne peut pas être développé.
Boutons simples
Les boutons devraient toujours avoir un nom accessible. Pour la plupart des boutons, le nom sera le même que le texte écrit à l'intérieur du bouton. Dans certains cas, par exemple pour les boutons représentés par une icône, le nom accessible pourra être fourni par l'attribut aria-label
ou aria-labelledby
.
Interrupteurs
Un interrupteur possède généralement deux états : activé ou désactivé. Un troisième état hybride est disponible pour les interrupteurs qui contrôlent d'autres éléments tels que d'autres interrupteurs ou cases à cocher qui n'ont pas tous la même valeur. On pourra indiquer qu'un élément est un interrupteur ou non via l'attribut aria-pressed
en complément du rôle button
(si l'élément n'est pas déjà un élément de bouton natif) :
- Si
aria-pressed
n'est pas utilisé ou qu'il est défini avec l'état"undefined"
, le bouton n'est pas un interrupteur. - Si
aria-pressed="false"
est utilisé, le bouton est un interrupteur qui n'est pas actif/pressé. - Si
aria-pressed="true"
est utilisé, le bouton est un interrupteur qui est actif/pressé. - Si
aria-pressed="mixed"
est utilisé, le bouton est considéré comme partiellement actif.
On peut, par exemple, avoir un bouton « Couper le son » sur un lecteur audio. Dans ce cas, on peut indiquer que le son est éteint lorsque l'état aria-pressed
vaut true
. Le libellé utilisé pour un interrupteur ne doit pas changer lorsque l'état change. Dans notre exemple, le libellé reste « Couper le son » et un lecteur d'écran indiquera « L'interrupteur couper le son est actif" ou « L'interrupteur couper le son est inactif » selon la valeur de aria-pressed
. Si on souhaite avoir un changement de libellé et passer de « Couper le son » à « Réactiver le son », un interrupteur ne serait pas approprié et aria-pressed
devrait alors être évité.
Interactions au clavier
Touche | Fonction |
---|---|
Entrée | Activer le bouton |
Espace | Activer le bouton |
Une fois le bouton activé, la gestion du focus dépendra du type d'action effectuée par le bouton. Ainsi, si cliquer sur le bouton déclenche l'ouverture d'une boîte de dialogue, le focus doit passer à cette boîte de dialogue. Si le bouton ferme une boîte de dialogue, le focus doit revenir sur le bouton qui permet d'ouvrir la boîte à moins que la fonction de la boîte de dialogue mène logiquement à un autre élément. Si le bouton modifie le contexte courant, le focus reste généralement sur le bouton (par exemple pour couper/remettre le son).
Fonctionnalités JavaScript nécessaires
Gestionnaires d'évènements nécessaires
Les boutons peuvent être manipulés avec une souris, le toucher et le clavier. Pour les éléments HTML natifs <button>
, l'évènement onclick
du bouton est déclenché lors du clic de la souris ou lorsque l'utilisatrice ou l'utilisateur utilise la touche Espace ou Entrée lorsque le bouton a le focus. Si un autre élément est utilisé pour créer un bouton, l'évènement onclick
ne se déclenche qu'au clic de la souris, y compris lorsqu'on utilise role="button"
. C'est pour cette raison qu'on doit ajouter des gestionnaires d'évènements distincts à l'élément afin de réagir aux appuis sur les touches Espace ou Entrée.
onclick
-
Gère l'évènement déclenché lorsque le bouton est activé avec un clic de souris ou au toucher.
onKeyDown
-
Gère l'évènement déclenché lorsque le bouton est activé à l'aide de la touche
Espace
ou
Entrée
du clavier (attention, il ne s'agit pas de l'évènement déprécié
onKeyPress
).
Modifier les valeurs des attributs
aria-pressed
La valeur de aria-pressed
définit l'état d'un interrupteur. Cet attribut peut avoir l'une des quatre valeurs suivantes :
true
,false
,mixed
,undefined
.
Exemples
Exemple de bouton simple
Dans cet exemple, on a un élément <span>
pour lequel on a mis le rôle button
. Comme il s'agit d'un élément <span>
, l'attribut tabindex
est nécessaire pour permettre au bouton de recevoir le focus et de s'inscrire dans l'ordre des tabulations. Le style CSS inclus permet de transformer visuellement l'élément <span>
afin qu'il ressemble à un bouton et pour fournir une indication visuelle lorsque celui-ci a le focus.
Les gestionnaires d'évènements handleBtnClick
et handleBtnKeyDown
exécutent l'action du bouton lorsqu'il est activé avec un clic de souris ou au clavier avec la touche Espace ou Entrée. Dans cet exemple, l'action consiste à ajouter un nouveau nom à une liste de noms.
Vous pouvez essayer l'exemple en ajoutant un nom dans le champ texte. Le bouton ajoutera ensuite le nom à la liste.
HTML
<h1>Exemple de bouton avec ARIA</h1>
<ul id="nameList"></ul>
<label for="newName">Saisissez votre nom :</label>
<input type="text" id="newName" />
<span
role="button"
tabindex="0"
onclick="handleCommand(event)"
onKeyDown="handleCommand(event)"
>Ajouter le nom</span
>
CSS
[role="button"] {
padding: 2px;
background-color: navy;
color: white;
cursor: default;
}
[role="button"]:hover,
[role="button"]:focus,
[role="button"]:active {
background-color: white;
color: navy;
}
ul {
list-style: none;
}
JavaScript
function handleCommand(event) {
// Gère à la fois l'activation à la souris
// et au clavier
// Les touches autres que Entrée et Espace ne devraient
// déclencher de commande
if (
event instanceof KeyboardEvent &&
event.key !== "Enter" &&
event.key !== " "
) {
return;
}
// On récupère la valeur du nouveau nom à partir
// du champ en saisie
let newNameInput = document.getElementById("newName");
let name = newNameInput.value;
newNameInput.value = ""; // On vide le champ texte
newNameInput.focus(); // On passe le focus au champ texte pour
// permettre la saisie d'un autre nom
// On évite d'ajouter des noms vides à la liste
if (name.length > 0) {
listItem = document.createElement("li");
listItem.appendChild(document.createTextNode(name));
// On ajoute le nouveau nom à la liste.
let list = document.getElementById("nameList");
list.appendChild(listItem);
}
}
Exemple d'interrupteur
Dans le fragment qui suit, on convertit un élément <span>
en interrupteur grâce au rôle button
et à l'attribut aria-pressed
. Lorsque le bouton est activé, aria-pressed
change de valeur et alterne entre true
et false
.
HTML
<button type="button" onclick="handleBtnClick()" onKeyDown="handleBtnKeyDown()">
Couper le son
</button>
<span
role="button"
tabindex="0"
aria-pressed="false"
onclick="handleBtnClick(event)"
onKeyDown="handleBtnKeyDown(event)">
Couper le son
</span>
<audio
id="audio"
src="https://soundbible.com/mp3/Tyrannosaurus%20Rex%20Roar-SoundBible.com-807702404.mp3">
Votre navigateur ne prend pas en charge l'élément <code>audio</code>.
</audio>
CSS
button,
[role="button"] {
padding: 3px;
border: 2px solid transparent;
}
button:active,
button:focus,
[role="button"][aria-pressed="true"] {
border: 2px solid #000;
}
JavaScript
function handleBtnClick(event) {
toggleButton(event.target);
}
function handleBtnKeyDown(event) {
// On vérifie si les touches Entrée ou Espace sont pressées
if (event.key === " " || event.key === "Enter" || event.key === "Spacebar") {
// Prise en charge de "Spacebar" pour IE11
// On empêche le défilement par défaut lorsque
// la touche espace est utilisée
event.preventDefault();
toggleButton(event.target);
}
}
function toggleButton(element) {
var audio = document.getElementById("audio");
// On vérifie si le bouton est pressé
var pressed = element.getAttribute("aria-pressed") === "true";
// On fait alterner aria-pressed vers l'état opposé
element.setAttribute("aria-pressed", !pressed);
// On modifie l'état de lecture du fichier audio
if (pressed) {
audio.pause();
} else {
audio.play();
}
}
Résultat
Accessibilité
Les boutons sont des contrôles interactifs et, à ce titre, peuvent recevoir le focus. Si le rôle button
est ajouté à un élément qui ne peut recevoir le focus nativement (comme <span>
, <div>
ou <p>
), l'attribut tabindex
devra être utilisé afin de permettre le focus sur le bouton.
Attention :
Lorsqu'on utilise des liens avec le rôle button
, il faut rajouter un gestionnaire d'évènement pour la touche Espace. En effet, les boutons s'activent avec Espace ou Entrée tandis que, nativement, les liens ne se déclenchent qu'avec Entrée.
Lorsqu'on utilise le rôle button
, les lecteurs d'écran annonce l'élément comme un bouton, généralement en énonçant « clic » suivi du nom accessible du bouton. Le nom accessible correspond au contenu de l'élément ou à la valeur de aria-label
ou à l'élément référencé avec l'attribut aria-labelledby
, ou à une description si elle existe.
Bonnes pratiques
Si un lien effectue l'action d'un bouton, fournir role="button"
à l'élément permettra aux outils d'assistance de comprendre la fonction de l'élément. Toutefois, une meilleure solution consiste à ajuster l'aspect visuel afin qu'il corresponde à la fonction et au rôle ARIA. Lorsque c'est possible, il est recommandé d'utiliser les boutons HTML natifs (<button>
, <input type="button">
, <input type="submit">
, <input type="reset">
et <input type="image">
) plutôt que le rôle button
. En effet, les boutons HTML natifs sont pris en charge par l'ensemble des agents utilisateurs et outils d'assistance et satisfont aux règles de gestion du focus et du clavier, sans qu'il soit nécessaire d'ajouter des adaptations.
Spécifications
Specification |
---|
Accessible Rich Internet Applications (WAI-ARIA) # button |
Unknown specification |
Notes
Attributs ARIA utilisés
Ressources complémentaires
- Sémantique native forte en HTML5
- Notes sur l'utilisation d'ARIA en HTML
- Exemple de code officiel WAI-ARIA
- Rôle ARIA
menubutton
- Rôles WAI-ARIA
ARIA : rôle alert
Utilisation du rôle alertdialog
ARIA: application role
ARIA : rôle article
Utilisation du rôle banner
ARIA : le rôle button
ARIA: cell role
Utilisation du rôle checkbox
ARIA: columnheader role
ARIA: combobox role
ARIA: command role
ARIA: comment role
ARIA: complementary role
ARIA: composite role
ARIA: contentinfo role
ARIA: definition role
Utilisation du rôle dialog
ARIA: directory role
ObsolèteARIA: document role
ARIA: document structural roles
ARIA: feed role
ARIA: figure role
ARIA: form role
ARIA: generic role
ARIA: grid role
ARIA: gridcell role
Utiliser le rôle group
ARIA: heading role
ARIA: img role
ARIA: input role
ARIA: landmark role
Utiliser le rôle link
ARIA: list role
Utiliser le rôle listbox
ARIA: listitem role
Utiliser le rôle log
ARIA: main role
ARIA: mark role
ARIA: marquee role
ARIA: math role
ARIA: menu role
ARIA: menubar role
ARIA: menuitem role
ARIA: menuitemcheckbox role
ARIA: menuitemradio role
ARIA: meter role
ARIA: navigation role
ARIA: none role
ARIA: note role
ARIA: option role
Utiliser le rôle presentation
Utiliser le rôle progressbar
ARIA: radio role
ARIA: radiogroup role
ARIA: range role
ARIA: region role
ARIA: roletype role
ARIA: row role
ARIA: rowgroup role
ARIA: rowheader role
ARIA: scrollbar role
ARIA: search role
ARIA: searchbox role
ARIA: section role
ARIA: sectionhead role
ARIA: select role
ARIA: separator role
Utiliser le rôle slider
ARIA: spinbutton role
Utiliser le rôle status
ARIA: structure role
ARIA: suggestion role
Utilisation du groupe switch
ARIA: tab role
ARIA: table role
ARIA: tablist role
ARIA: tabpanel role
ARIA: term role
Utiliser le rôle textbox
ARIA: timer role
ARIA: toolbar role
ARIA: tooltip role
ARIA: tree role
ARIA: treegrid role
ARIA: treeitem role
ARIA: widget role
ARIA: window role