Comprendre WAI-ARIA, un guide complet
Dans cet article, Kate Kalcevich explique quand et comment utiliser ARIA afin d'aider les personnes handicapées utilisant des technologies d'assistance pour naviguer sur Internet. Allons-y!
L'Initiative pour l'accessibilité du Web - Applications Internet riches accessibles (WAI-ARIA) est une spécification technique qui fournit des directives sur la manière d'améliorer l'accessibilité des applications Web. Alors que les directives d'accessibilité au contenu Web (WCAG) se concentrent davantage sur le contenu Web statique, WAI-ARIA s'attache à rendre les interactions plus accessibles.
Les interactions sur le Web sont connues pour être inaccessibles, alors qu'elles font souvent partie des fonctions les plus critiques telles que :
- la soumission d'une demande d'emploi,
- l'achat dans un magasin en ligne, ou
- la réservation d'un rendez-vous médical.
Je suis actuellement responsable de l'innovation en matière d'accessibilité chez Fable, une entreprise qui met en relation des organisations avec des personnes handicapées pour des recherches sur les utilisateurs et des tests d'accessibilité, et qui propose des formations personnalisées aux équipes numériques afin qu'elles acquièrent les compétences nécessaires à la création de produits inclusifs.
En tant qu'instructeur pour le développement Web accessible, je passe beaucoup de temps à examiner le code source des sites Web et des applications Web, et ARIA est l'une des choses que je vois les développeurs utiliser le plus mal.
HTML
Lorsque vous utilisez des éléments HTML tels que input
, select
et button
, il se passe deux choses concernant l'accessibilité : les informations sur l'élément sont transmises au DOM (Document Object Model) et dans un arbre d'accessibilité. Les technologies d'assistance peuvent accéder aux nœuds de l'arbre d'accessibilité pour comprendre :
- de quel type d'élément il s'agit en vérifiant son rôle, par exemple, une case à cocher ;
- dans quel état se trouve l'élément, par exemple, coché/non coché ;
- le nom de l'élément, par exemple, "Inscrivez-vous à notre bulletin d'information".
L'autre chose que vous obtenez en utilisant les éléments HTML est l'interactivité du clavier. Par exemple, une case à cocher peut être mise en focus à l'aide de la touche de tabulation et sélectionnée à l'aide de la barre d'espacement (les interactions spécifiques peuvent varier selon le navigateur et le système d'exploitation, mais le fait est qu'elles sont disponibles et normalisées sur tous les sites Web lorsque vous utilisez des éléments HTML).
Lorsque vous n'utilisez pas les éléménts HTML modernes, par exemple, si vous construisez votre propre sélection personnalisée à l'aide de <div>
et de <span>
ou si vous utilisez une bibliothèque de composants, vous devez faire un travail supplémentaire pour fournir des informations sur l'élément et construire l'interactivité du clavier pour les utilisateurs de technologies d'assistance. C'est là que l'ARIA entre en jeu.
ARIA
Les applications Internet riches accessibles (ARIA) comprennent un ensemble de rôles et d'attributs qui définissent les moyens de rendre le contenu et les applications Web plus accessibles aux personnes handicapées.
Vous pouvez utiliser ARIA pour transmettre des informations à l'arbre d'accessibilité. Les rôles et attributs ARIA n'incluent pas d'interactivité avec le clavier. L'ajout de role="button"
à une <div>
ne le fait pas réagir lorsque vous appuyez sur la touche Entrée de votre clavier — cela, vous devez le construire en utilisant JavaScript ou un autre langage. Toutefois, le guide ARIA des pratiques de création de site comprend une liste de l'interactivité du clavier décrivant ce qui qui devrait être ajouté à divers composants tels que les accordéons, les boutons, les carrousels, etc.
Rôles
Commençons par les rôles. Qu'est-ce que c'est que ce truc dans le code ci-dessous ?
<div className="dd-wrapper">
<div className="dd-header">
<div className="dd-header-title"></div>
</div>
<div className="dd-list">
<button className="dd-list-item"></button>
<button className="dd-list-item"></button>
<button className="dd-list-item"></button>
</div>
</div>
Il s'agit en fait d'un extrait de code que j'ai trouvé en ligne à partir d'un élément select
pour React. L'élément est complètement méconnaissable à partir du code, et c'est exactement le problème que rencontrerait toute technologie d'assistance — elle ne peut pas dire à l'utilisateur ce qu'est cet élément ni comment interagir avec lui car il n'y a pas de rôle ARIA.
Regardez ce que nous pouvons faire ici :
<div className="dd-wrapper" role="listbox"></div>
Peut-être ne connaissez-vous pas bien les listbox, c'est un type de select
qu'un utilisateur de lecteur d'écran pourrait reconnaître et avec lequel il saurait interagir. Maintenant, vous pourriez simplement utiliser <select>
, et vous n'auriez pas à lui donner de rôle car il en a déjà un que le DOM et l'arbre d'accessibilité reconnaîtront, mais je sais que ce n'est pas toujours une option réalisable.
Un rôle indique à un utilisateur de technologie d'assistance ce qu'est la chose avec laquelle il peut interagir, alors assurez-vous d'utiliser le bon rôle. Un bouton est très différent d'une bannière. Choisissez un rôle qui correspond à la fonction du composant que vous construisez.
Une autre chose que vous devez savoir sur les rôles ARIA est qu'ils remplacent le rôle inhérent d'un élément HTML.
<img role="button" />
Il ne s'agit plus d'une image mais d'un bouton. Il y a très peu de raisons de faire cela, et à moins de savoir exactement ce qu'on fait et pourquoi, je m'abstiendrais de remplacer les rôles HTML existants. Il existe de nombreuses autres façons d'y parvenir qui sont plus logiques du point de vue de l'accessibilité et de la robustesse du code :
<button><img src="image.png" alt="Imprimer" /></button>
<input type="image" src="image.png" alt="Imprimer" />
<button style="background : url(image.png)" />Imprimer</button>
Si vous créez un composant, vous pouvez consulter le modèle de ce composant dans Le guide ARIA des bonnes pratiques de construction de sites, qui contient des informations sur le ou les rôles à utiliser. Vous pouvez également consulter tous les rôles disponibles dans la documentation Web mdn.
En résumé, si vous construisez un élément qui n'a pas de balise HTML sémantique pour le décrire (c'est-à-dire tout élément interactif construit à l'aide de <div>
ou <span>
), il doit avoir un rôle ARIA pour que les technologies d'assistance puissent reconnaître ce qu'il est.
États et propriétés (également appelés attributs ARIA)
En plus de savoir ce qu'est un élément, s'il a un état (par exemple, caché, désactivé, invalide, en lecture seule, sélectionné, etc.) ou change d'état (par exemple, coché/non coché, ouvert/fermé, etc.), vous devez indiquer aux utilisateurs de technologies d'assistance quel est son état actuel et son nouvel état chaque fois qu'il change. Vous pouvez également partager certaines propriétés d'un élément. La différence entre les états et les propriétés n'est pas vraiment claire ou importante, alors appelons-les simplement des attributs.
Voici quelques-uns des attributs ARIA les plus courants que vous pourriez être amenés à utiliser :
- aria-checked
Il est utilisé avec ="true" ou ="false" pour indiquer si les cases à cocher et les boutons radio sont actuellement cochés ou non. - aria-current
Il est utilisé avec ="true" ou ="false" pour indiquer la page actuelle dans le fil d'Ariane ou la pagination. - aria-describedby
Elle est utilisée avec l'id d'un élément pour ajouter plus d'informations à un champ de formulaire en plus de son étiquette.aria-describedby
peut être utilisée pour donner des exemples du format requis pour un champ, par exemple une date, ou pour ajouter un message d'erreur à un champ de formulaire.
<label for="anniversaire">Anniversaire</label>
<input type="text" id="birthday" aria-describedby="date-format" />
<span id="date-format">MM-DD-YYYY</span>
- aria-expanded
Il est utilisé avec ="true" ou ="false" pour indiquer si le fait d'appuyer sur un bouton affichera plus de contenu. Les exemples incluent les accordéons et les éléments de navigation avec sous-menus.
<button aria-expanded="false">Produits</button>
Ceci indique que le menu Produits ouvrira un sous-menu (par exemple, de différentes catégories de produits). En revanche, si vous le codez comme ceci...
<a href="/produits/">Produits</a>
...l'utilisateur s'attendra à ce qu'il s'agisse d'un lien et à ce qu'en cliquant dessus, il accède à une nouvelle page. Ce que le bouton plus aria-expanded
dit à un utilisateur de technologie d'assistance, c'est qu'il ne va pas vers une nouvelle page, mais qu'il reste en fait sur la même page et ouvre un sous-menu. Cette simple différence entre <bouton>
et <a>
et l'ajout d'aria-expanded
communique tellement sur la façon d'interagir avec les éléments et ce qui se passera lorsque vous le ferez.
- aria-hidden
Il est utilisé avec ="true" ou ="false" pour cacher quelque chose qui est visible, mais que vous ne voulez pas que les utilisateurs de technologies d'assistance connaissent. Utilisez-le avec une extrême prudence car il y a très peu de cas où vous ne voulez pas que des informations équivalentes soient présentées.
Un cas d'utilisation intéressant que j'ai vu est une carte comportant à la fois une image et le titre textuel de la carte renvoyant à la même page, mais structurée comme deux liens distincts. Imaginez un grand nombre de ces cartes sur une page. Pour un utilisateur de lecteur d'écran, il entendrait chaque lien lu deux fois. Les liens d'image ont donc utilisé aria-hidden="true"
. La solution idéale serait de combiner les liens en un seul qui contiendrait à la fois une image et le titre du texte, mais le codage dans la vie réelle n'est pas toujours idéal et vous n'avez pas toujours ce niveau de contrôle.
Notez que cela enfreint la quatrième règle d'ARIA (que nous aborderons plus tard), mais d'une manière qui ne nuit pas à l'accessibilité. Utilisez-la avec une extrême prudence lorsqu'il n'existe pas de meilleure solution de contournement et que vous l'avez testée avec des utilisateurs de technologies d'assistance.
- aria-required
Il est utilisé avec ="true" ou ="false" pour indiquer si un élément de formulaire doit être rempli pour que le formulaire puisse être soumis.
Si vous construisez un composant, vous pouvez consulter les attributs de ce composant dans le guide des pratiques de création ARIA. La docs web mdn couvre les états et les propriétés ainsi que les rôles ARIA.
Gardez à l'esprit que tous ces attributs ARIA indiquent quelque chose à l'utilisateur, mais que vous devez toujours coder la chose que vous lui dites. aria-checked="true"
ne vérifie pas réellement une case à cocher ; il indique simplement à l'utilisateur que la case est cochée, donc il vaut mieux que ce soit vrai ou vous aggraverez les choses au lieu de les améliorer pour l'accessibilité. L'exception serait aria-hidden="true"
qui supprime un élément de l'arbre d'accessibilité, le cachant effectivement à toute personne utilisant une technologie d'assistance qui ne peut pas voir.
Nous savons donc maintenant comment utiliser ARIA pour expliquer ce qu'est un élément, dans quel état il se trouve et quelles sont ses propriétés. La dernière chose que je vais aborder est la gestion du focus.
Gestion du focus
Tout ce qui est interactif sur un site Web ou une application Web doit pouvoir recevoir le focus. Tout le monde n'utilise pas une souris, un trackpad ou un écran tactile pour interagir avec les sites. De nombreuses personnes utilisent leur clavier ou un dispositif technologique d'assistance qui émule un clavier. Cela signifie que pour tout ce sur quoi vous pouvez cliquer, vous devez également être capable d'utiliser la touche de tabulation ou les touches fléchées pour l'atteindre et la touche Entrée, et parfois la barre d'espacement, pour le sélectionner.
Il y a trois concepts dont vous devrez tenir compte si vous utilisez <div>
et <span>
pour créer des éléments interactifs :
- Vous devez ajouter tabindex="0" pour qu'un clavier ou un émulateur puisse se concentrer sur eux.
- Pour tout ce qui accepte la saisie au clavier, vous devez ajouter un écouteur d'événements (Event Listener) pour écouter les pressions sur les touches.
- Vous devez ajouter le rôle approprié pour qu'un utilisateur de lecteur d'écran puisse identifier l'élément que vous avez construit.
N'oubliez pas que les contrôles HTML natifs acceptent déjà le focus et l'entrée clavier et ont des rôles inhérents. C'est exactement ce que vous devez faire lorsque vous créez des éléments personnalisés à partir de HTML non sémantique.
Ben Myers fait une plongée profonde dans la transformation d'une div en bouton, et je vais partager quelques extraits de son exemple ici. Remarquez le tabindex
et le role
:
<div tabindex="0" role="button" onclick="doSomething() ;">
Cliquez sur moi !
</div>
Et vous aurez besoin de JavaScript pour écouter les pressions sur les touches :
const ENTER = 13
const SPACE = 32
// Sélectionnez votre bouton et enregistrez-le dans 'myButton'.
myButton.addEventListener('keydown', function (event) {
if (event.keyCode === ENTER || event.keyCode === SPACE) {
event.preventDefault() // Empêche les soumissions involontaires de formulaires, les défilements de pages, etc.
doSomething(event)
}
})
Lorsqu'il s'agit de déterminer les touches à écouter, je vous suggère de consulter le composant que vous construisez dans le guide des pratiques de création ARIA et de suivre les recommandations relatives à l'interaction avec le clavier.
Erreurs courantes
Pour avoir examiné beaucoup de code au cours de ma vie, je peux attester que certaines erreurs d'accessibilité sont régulièrement commises. Voici une liste des erreurs les plus courantes que je trouve et comment les éviter :
Utilisation d'un attribut aria-labelledby faisant référence à un ID qui n'existe pas
Par exemple, une modale qui a un titre dans la modale mais dont l'attribut aria-labelledby
fait référence à quelque chose d'autre qui n'existe plus. C'est probablement quelque chose qui a été supprimé par un autre développeur qui n'a pas réalisé que la connexion aria-labelledby
était là. Pour éviter cela, le titre de la modale aurait pu être un <h1>
et soit aria-labelledby
aurait pu faire référence au <h1>
, soit on aurait pu mettre le focus sur le <h1>
lorsque la modale s'ouvre et, du coup, un utilisateur de lecteur d'écran pourrait savoir ce qui se passe, tant que role="dialog"
est également utilisé. Essayez d'éviter les structures fragiles qui, si quelqu'un d'autre venait à modifier le code, se briseraient facilement.
Ne pas déplacer le focus dans la nouvelle modale lorsqu'elle s'ouvre
Combien de fois ai-je vu un utilisateur de lecteur d'écran continuer à naviguer sur la page située sous la modale, parce qu'il ne savait pas qu'une modale s'était ouverte, soit être complètement perdu parce qu'il ne trouvait pas le contenu de la modale. Il existe plusieurs façons de déplacer le focus au sein d'une modale, mais l'une des méthodes les plus récentes consiste à ajouter inert
au repère <main>
(et, bien sûr, s'assurer que la modale n'est pas à l'intérieur de <main>
). Inert bénéficie d'une meilleure prise en charge par les navigateurs ces derniers temps. Pour en savoir plus, consultez l'article de Lars Magnus Klavenes intitulé Accessible modal dialogs using inert.
Ajout de rôles qui font double emploi avec le HTML
En général, il est inutile d'écrire <button role="button">
. Il existe un cas où il pourrait être judicieux de le faire. VoiceOver et Safari suppriment la sémantique des éléments de liste lorsque list-style : none
est utilisé. C'est fait exprès car si rien n'indique à un utilisateur voyant que le contenu est une liste, pourquoi dire à un utilisateur de lecteur d'écran qu'il s'agit d'une liste ? Si vous voulez passer outre, vous pouvez ajouter un role="list"
ARIA explicite à <ul>
.
Adrian Roselli dit qu'une liste non stylisée n'étant pas annoncée comme une liste "...peut ne pas être un gros problème à moins que les tests utilisateurs disent que vous avez vraiment besoin d'une liste." Je suis d'accord avec lui sur ce point, mais je suis aussi d'accord avec la correction si vos tests utilisateurs montrent que c'est bénéfique.
Ajout de tabindex="0"
à tous les éléments
Parfois, les développeurs commencent à utiliser un lecteur d'écran et supposent que la tabulation est la seule façon de naviguer et que, par conséquent, tout ce qui ne comporte pas de tabindex
n'est pas accessible. Ce n'est PAS vrai. N'oubliez pas que si vous ne savez pas comment utiliser un lecteur d'écran, vous ne pouvez pas résoudre les problèmes d'utilisabilité. Rencontrez un utilisateur quotidien de lecteur d'écran pour les résoudre.
Utilisation de rôles enfants sans rôles parents
Par exemple, role="option"
doit avoir un parent direct avec role="listbox"
.
<div role="listbox">
<ul>
<li role="option"></li>
</ul>
</div>
Le code ci-dessus n'est pas valide car il y a un <ul>
entre les éléments parent et enfant. Cela peut être corrigé en ajoutant un rôle de présentation pour essentiellement cacher le <ul>
de l'arbre d'accessibilité, comme <ul role="presentation">
.
Utilisation de role="menu" pour la navigation
La navigation d'un site Web est en réalité une table des matières et non un menu. Les menus ARIA ne sont pas destinés à être utilisés pour la navigation mais pour le comportement des applications, comme les menus d'une application de bureau. Utilisez plutôt <nav>
, et si vous avez des liens de navigation enfants, ceux-ci doivent être cachés jusqu'à ce qu'on appuie sur un bouton pour les afficher :
<nav aria-label="Main menu">
<button aria-expanded="false">Produits</button>
<ul hidden>
<li>Pyjama chat</li>
...
</ul>
</nav>
Si vous voulez en savoir plus, Heydon Pickering fait une plongée profonde dans la construction de systèmes de menus accessibles dans son article de Smashing Magazine.
En ce qui concerne la navigation, utiliser <nav>
plusieurs fois sur une page sans donner à chaque instance une étiquette unique signifie que les utilisateurs de lecteurs d'écran devront explorer chaque région de navigation pour trouver celle qu'ils recherchent. Un simple aria-label
sur chaque <nav>
rendra les choses beaucoup plus faciles.
<nav aria-label="Service client">
<ul>
<li><a href="#">Aide</a></li>
<li><a href="#">Suivi des commandes</a></li>
<li><a href="#">Expédition et livraison</a></li>
<li><a href="#">Retours</a></li>
<li><a href="#">Nous contacter</a></li>
<li><a href="#">Trouver un magasin</a></li>
</ul>
</nav>
Comment valider ARIA
Utilisez des vérificateurs d'accessibilité automatisés comme Axe ou les extensions WAVE lorsque vous exécutez votre code dans un navigateur. Les vérificateurs d'accessibilité comme Axe pour Visual Studio Code ou ESLint pour les éléments JSX vérifieront votre code à mesure que vous l'écrivez.
Écoutez votre code avec un lecteur d'écran. De même que vous ne publierez jamais un code sans l'exécuter dans un navigateur pour vous assurer qu'il fonctionne, de même l'utilisation d'un lecteur d'écran vous permettra de vérifier qu'il fonctionne pour tous les publics. NVDA est gratuit pour Windows, et VoiceOver est intégré aux Mac et iPhones. TalkBack est intégré aux téléphones Android.
Testez avec des utilisateurs de technologies d'assistance. Je considère cela comme obligatoire pour toute grande organisation qui dispose d'un budget pour l'accessibilité (et elles devraient toutes le faire). Il existe des entreprises qui peuvent recruter des utilisateurs de technologies d'assistance pour les tests ou effectuer des tests utilisateurs pour vous, et l'entreprise pour laquelle je travaille peut fournir des délais de 2 jours pour les tests utilisateurs qui sont, ou non, modérés par vous pour soutenir les tests d'accessibilité à grande échelle.
Frameworks et bibliothèques de composants
Si vous utilisez un framework Web, une façon d'alléger un peu le travail de construction pour l'accessibilité est d'utiliser une bibliothèque de composants intégrant l'accessibilité. J'ajouterai une mise en garde toutefois : l'accessibilité peut être complexe et tout ce qui se prétend accessible n'est pas toujours utilisable par les utilisateurs de technologies d'assistance. La meilleure façon de garantir l'accessibilité est de toujours tester avec les utilisateurs pour lesquels vous construisez.
Voici quelques points de départ pour votre recherche :
Conclusion
Avec un peu de chance, cet article aura démystifié ARIA pour vous. Comme un langage secret connu de la seule l'élite de l'accessibilité, il a ses propres règles Fight Club-esque.
La première règle de l'ARIA est "N'utilisez pas l'ARIA". Un <button>
sera toujours mieux que <div role="button">
.
Deuxièmement, ne remplacez pas la sémantique native. Au lieu de <button role="heading">
, utilisez <h3><button>
.
Enfin, n'oubliez jamais que tous les éléments interactifs ARIA doivent fonctionner avec le clavier.
N'utilisez pas role="presentation"
ou aria-hidden="true"
sur un élément focalisable. <button role="presentation">
signifie que vous cachez ce bouton uniquement aux utilisateurs de technologies d'assistance. Ce n'est pas seulement inaccessible, c'est carrément exclure certains utilisateurs.
Dernier point, mais non le moindre, tous les éléments interactifs doivent avoir un nom accessible. Il existe de nombreuses façons de le faire, et en voici quelques-unes :
<button>Imprimer</button> (le nom est le texte du bouton)
<div aria-label="Settings"><svg></div> (l'aria-label attribue un nom)
<div aria-labelledby="myName">
<h1 id="myName">La rubrique</h1>
</div>
<label for="name">Nom</label>
<input type="text" id="name" />
Je pense volontiers à ARIA comme à un outil utilisé par l'équipe d'élite des opérations spéciales à laquelle vous faites appel pour vos défis d'accessibilité les plus difficiles. Peut-être ai-je juste toujours voulu faire des pompes à un bras comme Emily Blunt dans Edge of Tomorrow, et c'est ce qui s'en rapproche le plus. Quoi qu'il en soit, j'espère que tout ceci vous a été utile et que vous n'êtes plus confus au sujet d'ARIA. Allez-y et construisez des choses accessibles !