WAI-ARIA et HTML5
Introduction
Au cours des dernières années, le Web est devenu de plus en plus interactif. L’arrivée de HTML5 et le développement des différentes librairies JavaScript y ont largement contribué.
WAI-ARIA est la réponse du W3C à cette évolution du Web. En application au critère 4.1.2, il s’agit d’un ensemble de techniques permettant de fournir aux utilisateurs d’outils d’adaptation des informations sur le nom, le rôle, l’état, les propriétés et les valeurs de chaque composant interactif.
Le Web étant un environnement toujours en évolution, il en va de même de HTML5 et WAI-ARIA. Cette dernière spécification, publiée pour la première fois en 2014, en est d’ailleurs déjà à la version 1.2, depuis juin 2023. Il s’agit d’une évolution rapide pour une recommandation officielle du W3C.
La prise en charge des navigateurs et des outils d’adaptation est elle aussi en évolution. Il faut donc se tenir à jour et lire les articles qui se publient régulièrement à ce sujet.
Le présent document est une introduction. Pour approfondir le sujet et comprendre comment utiliser correctement WAI-ARIA, voir la section des références en fin de document.
Étant donné le caractère évolutif et parfois même fluctuant de la prise en charge de WAI-ARIA par les différentes environnements (combinaisons de navigateurs et de lecteurs d’écran), il est impératif de s’assurer du bon résultat dans le cadre de tests fonctionnels avec plusieurs environnements.
WAI-ARIA est une couche d’accessibilité qui permet de transmettre aux utilisateurs via leur outil d’adaptation des informations supplémentaires nécessaires à une bonne compréhension des éléments interactifs. Pour ce faire, les attributs WAI-ARIA viennent s’ajouter aux balises HTML.
WAI-ARIA n’est pas une solution de correction pour un contenu Web mal structuré ou pour des balises HTML mal utilisées. Une mauvaise utilisation de WAI-ARIA peut même aboutir à des résultats contraires aux objectifs.
Dans l’ordre, les différentes couches de conception s’ajoutent les unes aux autres et chaque couche doit être solide afin de pouvoir y ajouter la suivante.
- Le code HTML, où chaque balise est utilisée selon son rôle sémantique;
- La feuille de style CSS, qui gère tous les aspects de la présentation;
- La programmation JavaScript, qui permet de créer des composants interactifs;
- Les attributs WAI-ARIA, qui viennent enrichir l’information pour les utilisateurs d’outils d’adaptation.
Il est d’ailleurs important de noter dès le départ que les attributs WAI-ARIA n’ont qu’une valeur « déclarative » qui ne change pas l’interaction habituellement prévue pour les balises HTML. Par exemple, WAI-ARIA pourrait permettre de redéfinir un titre de niveau 2 comme bouton, mais ne permettra pas d’interagir avec ce bouton tant que le nouveau comportement ne sera pas programmé en JavaScript.
Lorsqu’une fonction est déjà prévue en HTML, il est toujours préférable d’utiliser une balise HTML pour remplir cette fonction plutôt que d’assigner un nouveau rôle à une autre balise et d’en reprogrammer le comportement.
WAI-ARIA est une couche finale que l’on ne doit pas utiliser si l’on n’en a pas besoin. En anglais, on dit d’ailleurs : « No ARIA is better than bad ARIA ». C’est une maxime à ne pas oublier.
Le W3C a aussi défini la façon dont les outils d’adaptation doivent interpréter les attributs WAI-ARIA.
- Le rôle, le nom et l’état de chaque élément,
- Sa relation avec les autres éléments.
Ces informations sont transmises via une API (interface de programmation applicative) d’accessibilité. Les navigateurs prennent en charge une ou plusieurs API :
Windows :
- Firefox, Chrome, Edge, Opera et Yandex prennent en charge MSAA/IAccessible et IAccessible2;
- Internet Explorer, aujourd’hui arrivé en fin de vie, prenait en charge MSAA/IAccessible et UIAExpress.
OSX :
- Safari et Chrome prennent en charge NSAccessibility.
iOS :
- Safari et Chrome prennent en charge UIAccessibility.
Les attributs WAI-ARIA sont interprétés automatiquement par le navigateur et transmis à la couche d’accessibilité du système d’exploitation puis à l’outil d’adaptation.
Aux éléments de contrôle actuels : case à cocher, bouton radio, boutons, boutons image, téléversement de fichier, HTML5 introduit de nouveaux types d’entrées, sous la forme de valeurs de l’attribut type
:
- Glissière (
range
), - Boîtes de texte :
- texte,
- recherche (
search
), - téléphone (
tel
), - URL (
url
), - courriel (
email
), - mot de passe (
password
).
- Dates et heures (
date
,time
,datetime
), - Nombres (
number
), - Sélection de couleur (
color
).
HTML5 définit aussi de nouvelles balises de champs et de nouveaux attributs de formulaire :
- Résultat d’un calcul ou d’un affichage (
<output>
); - Progression (
<progress>
); - Jauge (
<meter>
); - Obligatoire (
required
); - Limites et incréments (
min
,max
,step
); - Autocomplétion, listes;
- Espace réservé (
placeholder
); - Autofocus;
- Éléments interactifs;
- Menus;
- Détails (
<details>
) et sa balise enfant de résumé (<summary>
).
Un autre apport significatif du HTML5 est l’ajout de balises visant à structurer des sections (ou régions) d’une page :
- Contenu d’introduction (
<header>
); - Pied de page (
<footer>
); - Navigation (
<nav>
); - Contenu principal (
<main>
); - Article, composition autonome (
<article>
); - Élément aparté (
<aside>
); - Section générique (
<section>
).
Tous ces changements, dont la liste n’est pas exhaustive, visent à :
- Une meilleure cohérence dans l’expérience utilisateur avec les applications de bureau;
- Moins de développement personnalisé de composants;
- Du HTML plus sémantique. Ex. :
<article>
,<header>
,<footer>
, plutôt que<div>
.
Tous les nouveaux éléments de HTML5 doivent être reconnus par l’API d’accessibilité.
Pour ce faire, WAI-ARIA propose 3 types d’attributs : rôles, états et propriétés.
- Rôle : Type de l’élément
- attribut
role
(dont la valeur précise ce rôle) - exemples de rôles : ceux de régions ARIA présentés à la règle 1.3 Adaptable – Perception de la structure, ou encore,
menubar
,tablist
,alert
, etc.
- attribut
- État : caractéristique dynamique d’un élément
- attribut aria-*
- exemples :
aria-checked
,aria-selected
,aria-current
,aria-hidden
, etc.
- Propriété : caractéristique statique d’un élément
- attribut aria-*
- exemples :
aria-required
,aria-checked
,aria-label
,aria-describedby
,aria-haspopup
, etc.
De l’aveu même du W3C, la différence entre état et propriété est assez subtile. c’est pourquoi les deux sont souvent regroupés sous le titre « États et propriétés ».
À chacun de ceux-ci peut s’appliquer une valeur qui peut prendre différentes formes :
- valeurs boléennes
true
oufalse
; - référence à un identifiant (ID);
- nombre;
- chaîne de caractères (string);
- etc.
Deux grandes règles doivent être respectées lorsqu’on a recours à WAI-ARIA.
1ère règle :
Utiliser un élément natif HTML si possible, plutôt que WAI-ARIA.
Exceptions :
- Incapacité d’habiller l’élément en CSS comme désiré;
- Fonction non disponible en HTML;
- Fonction disponible en HTML mais non prise en charge par les navigateurs ou les technologies d’adaptation.
2e règle :
Ne pas changer la sémantique native HTML, sauf cas particulier.
Exemple : Un titre de section qui soit en même temps un bouton.
À ne pas faire :
<h1 role="button">Nos services</h1>
À faire plutôt :
<h1><span role="button">Nos services</span></h1>
ou, mieux :
<h1><button>Nos services</button></h1>
Autrement dit…
Ajouter un rôle ne change :
- ni les comportement,
- ni les états,
- ni les propriétés.
Il s’agit uniquement de déclarer un rôle pour aider à comprendre sa fonction et à prévoir la façon d’interagir avec cet élément.
Changer le rôle d’un élément n’ajoute pas automatiquement les comportements (programmation), les propriétés et les états afférents; il faut les développer soi-même.
De plus, le rôle WAI-ARIA écrase le rôle sémantique natif.
Mauvais exemples d’écrasement de la sémantique
<h1 role="button">texte</h1>
devient un bouton dans la couche d’accessibilité, au même titre que<button>texte</button>
. Ainsi, la notion de niveau d’en-tête 1 (h1
) est perdue!<button role="heading">texte</button>
devient un titre dans la couche d’accessibilité, mais garde les comportement associés à un bouton en HTML.
Ajout d’information de contextualisation
Trois attributs WAI-ARIA permettent d’ajouter de l’information de contextualisation à des éléments pouvant recevoir le focus.
- L’attribut
aria-labelledby
permet d’associer un plusieurs éléments visibles à l’écran à un élément interactif en indiquant le ou les ID comme valeur. Par exemple, dans un formulaire présenté sous la forme d’un tableau de données ou chaque champ tire sa signification des titres de colonne et de ligne correspondants, ces titres peuvent être associés au champ en indiquant leur ID comme valeur de l’attributaria-labelledby
. - L’attribut
aria-describedby
joue sensiblement le même rôle et fonctionne de la même façon quearia-labelledby
. La nuance entre les deux est que dans le cas dearia-labelledby
, il s’agit de courts étiquettes alors qu’avecaria-describedby
, on peut associer des paragraphes entiers si nécessaire, qu’ils soient d’ailleurs visibles à l’écran ou placés hors-écran. - L’attribut
aria-label
, quant à lui, utilise plutôt une valeur présentée sous la forme d’une chaîne de caractères qui ne sont pas visibles à l’écran ou visibles seulement en partie. En effet, si une ou plusieurs étiquettes sont déjà visibles à l’écran, il faut plutôt utiliseraria-labelledby
. Toutefois, si l’on veut ajouter des éléments d’information supplémentaires à une étiquette déjà visible à l’écran, l’utilisation dearia-label
est toute indiquée. Dans ce cas, il est important de s’assurer que tout le texte faisant partie de l’étiquette visible soit répété intégralement dans la valeur duaria-label
, idéalement au début de la chaîne de caractères. Cette précaution, qui réfère au critère de succès 2.5.3 (WCAG 2.1), vise à s’assurer qu’un utilisateur de commandes vocales puisse facilement sélectionner un élément interactif doté d’une étiquette visible.
Contrôle de la présentation
Deux attributs WAI-ARIA permettent de contrôler la présentation de certains éléments :
role="presentation"
;aria-hidden
, qui peut recevoir la valeurtrue
oufalse
.
Le rôle de présentation
L’attribut role="presentation"
a pour effet d’effacer le rôle sémantique d’une balise et de ses descendants obligatoires. Par exemple, il peut être avantageux d’utiliser un tableau de présentation pour faciliter la disposition visuelle d’un formulaire d’évaluation où chaque item doit être coté de 1 à 5 à l’aide de boutons radio. Il y aura évidemment un problème d’étiquetage de chacun de ces boutons, dont nous avons déjà parlé dans la section précédente.
Ainsi, dans le contexte d’un tableau de présentation, on peut éviter beaucoup de verbiage inutile sur la balise <table> en lui retirant son rôle au moyen de role="presentation"
. Cela aura pour effet de masquer toute la structure du tableau (balises <tr>
, <th>
, <td>
) à l’API d’accessibilité. Cela va également éliminer toutes les informations sur la taille du tableau ainsi que les numéros de lignes et de colonnes, informations inutiles qui ne contribuent qu’à créer de la confusion pour l’utilisateur d’un lecteur d’écran.
aria-hidden
L’attribut aria-hidden
peut recevoir la valeur true
ou false
. Il s’agit d’une arme puissante qu’il faut utiliser seulement dans des cas particuliers. Cet attribut retire entièrement, dans l’arbre d’accessibilité du document, le contenu de la balise à laquelle il est appliqué, ainsi que tous les contenus et balises enfants. C’est donc dire qu’un contenu masqué avec aria-hidden="true"
sera masqué aux outils d’adaptation, sans toutefois être masqué visuellement.
Attention : La spécification WAI-ARIA n’autorise pas l’usage de aria-hidden="true"
sur des balises dont le contenu reçoit le focus, ou sur toute balise dont les éléments enfants sont focusables. On ne peut, par exemple, appliquer cet attribut sur la balise d’un lien ou d’un bouton recevant le focus.
Bon à savoir : Il importe de considérer toutes les personnes ayant des limitations, lorsqu’on s’interroge sur la pertinence d’employer aria-hidden="true"
. En effet, les personnes aveugles et malvoyantes ne sont pas les seules clientèles utilisant des outils d’adaptation reconnaissant l’instruction donnée par cet attribut.
Voici quelques exemples d’emploi de aria-hidden="true"
:
- Pour masquer des images purement décoratives, notamment celles intégrées depuis la balise <svg> ou à l’aide l’icônes sous forme de caractères textuels (voir l’exemple de code plus bas);
- Pour masquer des contenus dupliqués, tels que du texte répété.
Exemples de masquage d’icônes décoratives à l’aide de aria-hidden="true"
<button>
<svg aria-hidden="true">...</svg>
Fermer
</button>
<a href="...">
<span class="fa-regular fa-envelope" aria-hidden="true"></span>
Nous joindre
</a>...
Menus déroulants
Un menu déroulant utilise essentiellement des listes HTML imbriquées et trois rôles pour structurer une barre de menu : menubar
, menu
et menuitem
. Toutefois, il faut programmer les comportements pour l’utilisation au clavier. La barre de menu doit réagir comme celle d’une application bureautique, les flèches directionnelles perdant leur fonction habituelle de lecture pour se déplacer entre les menus ou à l’intérieur de ceux-ci.
C’est pourquoi, dès qu’on active le menu, le lecteur d’écran passe en mode formulaire, ce que l’on pourrait aussi appeler « mode interactif » ou « mode applicatif », puisqu’il s’agit d’imiter le fonctionnement d’une application. Un signal sonore sera émis par le lecteur d’écran pour confirmer ce changement de mode.
Voir aussi :
Explications techniques
Voici tous les rôles, état et propriétés impliqués :
- Un menu est un conteneur d’éléments qui représentent des choix. L’élément servant de menu a un rôle de
menu
ou demenubar
. - Les éléments contenus dans un menu sont des éléments enfants du menu ou de la barre de menus contenant et ont l’un des rôles suivants :
menuitem
, (ou)menuitemcheckbox
, (ou)menuitemradio
. - Si l’activation d’un
menuitem
ouvre un sous-menu, lemenuitem
est connu comme unmenuitem
parent. L’élément de menu d’un sous-menu est contenu dans ou appartient à son parentmenuitem
.
Un menuitem parent a l’étataria-haspopup
défini surmenu
outrue
. - Un menuitem parent a
aria-expanded
défini surfalse
lorsque son menu enfant n’est pas visible et défini surtrue
lorsque le menu enfant est visible. - Chaque élément du menu a un
tabindex
égal à-1
, sauf dans une barre de menus, où le premier élément est défini sur0
. - Si une barre de menus a une étiquette visible, l’élément avec le menu menubar a
aria-labelledby
défini sur une valeur qui fait référence à l’élément d’étiquetage. Sinon, l’élémentmenubar
a une étiquette fournie pararia-label
.
Panneaux à onglets
Les panneaux à onglets sont souvent imités visuellement en utilisant de simples liens. Toutefois, cette façon de faire crée de la confusion pour les utilisateurs d’un lecteur d’écran. L’utilisation des attributs WAI-ARIA permettent au lecteur d’écran d’identifier clairement ces éléments comme des onglets et d’identifier aussi l’onglet actif parmi la liste.
Comme il faut encore ici programmer l’interaction au clavier, afin de pouvoir se déplacer entre les onglets, le mode navigation sera suspendu au profit du mode interactif ou applicatif. Un signal sonore sera émis par le lecteur d’écran pour confirmer ce changement de mode.
Voir aussi :
Explications techniques
Voici tous les rôles, état et propriétés impliqués :
- L’élément qui sert de conteneur pour l’ensemble des onglets a un rôle
tablist
. - Chaque élément qui sert d’onglet a un rôle
tab
et est contenu dans l’élément ayant le rôletablist
. - Chaque élément qui contient le contenu du panneau d’un onglet a un rôle
tabpanel
. - Chaque élément avec un rôle
tab
possède la propriétéaria-controls
faisant référence à son élémenttabpanel
associé. - L’élément d’onglet actif a l’état
aria-selected
défini surtrue
et tous les autres éléments d’onglet l’ont défini surfalse
. - Chaque élément ayant un rôle
tabpanel
a la propriétéaria-labelledby
en se référant à son élémenttab
associé. - Si l’élément
tablist
est orienté verticalement, la propriétéaria-orientation
est définie survertical
. Notons que la valeur par défaut dearia-orientation
pour un élémenttablist
est horizontale; il est donc inutile de le préciser si c’est le cas.
Boites de dialogue
Une boite de dialogue doit répondre aux conditions suivantes :
- Lorsqu’une boite de dialogue apparait, le focus doit y être déplacé.
- La boite de dialogue doit être identifée en tant que boite de dialogue avec un identifiant qui en indique la fonction.
- Tout le contenu de la page en dehors de la boite de dialogue doit être masqué pour les outils d’adaptation.
- La boite de dialogue doit pouvoir être fermée avec le bouton prévu à cet effet ou avec la touche Échappe.
- À la fermeture de la boite de dialogue, le focus doit être ramené à l’élément qui en a déclenché l’ouverture.
Voir aussi :
Explications techniques
Voici tous les rôles, état et propriétés impliqués :
- L’élément qui sert de conteneur de dialogue a un rôle de
dialog
. - Tous les éléments requis pour faire fonctionner le dialogue sont les descendants de l’élément qui a un rôle
dialog
. Ces éléments doivent être eux-mêmes enchâssés dans un conteneur avec lerole="document"
. Dans le cas contraire, les contenus du dialogue qui ne reçoivent pas le focus ne seront pas lus par les outils d’adaptation dans certains navigateurs. - L’élément de conteneur de dialogue a
aria-modal
défini surtrue
.
(Voir la note à la fin de cette liste concernantaria-modal
etaria-hidden
.) - Le dialogue a soit :
- Une valeur définie pour la propriété
aria-labelledby
qui fait référence à un titre de boîte de dialogue visible. - Une étiquette spécifiée par
aria-label
. - Facultativement, la propriété
aria-describedby
est définie sur l’élément avec le rôledialog
pour indiquer quel élément ou quels éléments de la boîte de dialogue contiennent du contenu qui décrit l’objectif principal ou le message de la boîte de dialogue. La spécification d’éléments descriptifs permet aux lecteurs d’écran d’annoncer la description avec le titre de la boîte de dialogue et l’élément initialement ciblé lorsque la boîte de dialogue s’ouvre.
- Une valeur définie pour la propriété
Note concernant l’emploi de aria-modal
et aria-hidden
(traduction libre de l’ARIA Authoring Practices Guide – Modal Dialog) :
- L’attribut de propriété
aria-modal
a été introduit dans ARIA 1.1. Du fait de sa nouveauté, il peut être pris en charge de manière variable par les combinaisons de lecteurs d’écran et de navigateurs. - L’application de
aria-modal
à l’élément de dialogue remplace la technique d’emploi dearia-hidden
sur l’arrière-plan, pour informer les outils d’adaptation que le contenu en dehors d’un dialogue est inerte (non focusable). - Dans les anciennes implémentations de dialogue où
aria-hidden
est utilisé pour rendre le contenu en dehors du dialogue inerte, il est important que :aria-hidden
soit défini surtrue
pour chaque élément contenant une partie de la couche inerte;- l’élément de dialogue ne soit pas un descendant d’un élément ayant
aria-hidden
défini surtrue
.
Accordéons
L’utilisation de panneau accordéons est très populaire, notamment pour les foires aux questions. Un accordéon doit répondre aux conditions suivantes :
- Il doit être ouvert ou fermé à l’aide d’un bouton et non d’un lien.
- L’état doit être communiqué lorsque le focus atteint le bouton et tout changement d’état doit être immédiatement annoncé à l’utilisateur.
- Lorsqu’un accordéon est ouvert, le focus demeure sur le bouton d’ouverture, car le message de changement d’état suffit à confirmer le résultat de l’action.
Voir aussi :
Explications techniques
Voici tous les rôles, état et propriétés impliqués :
- Le libellé du titre de chaque en-tête d’accordéon est contenu dans une balise avec un rôle
button
(ou à l’intérieur d’une balise<button>
). - Chaque bouton d’en-tête d’accordéon est enveloppé par une balise d’en-tête de niveau approprié pour l’architecture d’information de la page.
- L’élément
button
est le seul élément à l’intérieur de la balise d’en-tête. Autrement dit, s’il existe d’autres éléments visuellement persistants, ils ne sont pas inclus dans la balise de titre. - Si le panneau d’accordéon associé à un en-tête d’accordéon est visible, l’élément
button
aaria-expanded
défini surtrue
. Si le panneau n’est pas visible,aria-expanded
est défini surfalse
. - L’élément du bouton d’en-tête accordéon a
aria-controls
défini sur l’ID de l’élément contenant le contenu du panneau accordéon.
Validation de formulaire
Il y a deux méthodes pour faire la validation d’un formulaire : champ par champ, lorsque le focus quitte le champ, et de façon globale au moment où l’on soumet le formulaire. Idéalement, il est souhaitable de combiner ces deux méthodes.
Voir aussi :
Explications techniques
Voici tous les rôles, état et propriétés impliqués :
- Les champs obligatoires ont
aria-required
défini àtrue
. - Les messages d’erreur sont immédiatement intégrés à l’étiquette du champ en erreur (
<label>
associé au champ). - Le message d’erreur est placé dans une balise
<span>
avecaria-live
défini àassertive
afin que le lecteur d’écran lise le message d’erreur au moment où il apparaît.
Pour approfondir le sujet et comprendre comment utiliser correctement WAI-ARIA, vous pouvez vous référer aux sources suivantes (en anglais) :