Propulsé par le RAAMM

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.

  1. Le code HTML, où chaque balise est utilisée selon son rôle sémantique;
  2. La feuille de style CSS, qui gère tous les aspects de la présentation;
  3. La programmation JavaScript, qui permet de créer des composants interactifs;
  4. 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
  • É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 ou false;
  • 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.

  1. 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’attribut aria-labelledby.
  2. L’attribut aria-describedby joue sensiblement le même rôle et fonctionne de la même façon que aria-labelledby. La nuance entre les deux est que dans le cas de aria-labelledby, il s’agit de courts étiquettes alors qu’avec aria-describedby, on peut associer des paragraphes entiers si nécessaire, qu’ils soient d’ailleurs visibles à l’écran ou placés hors-écran.
  3. 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 utiliser aria-labelledby. Toutefois, si l’on veut ajouter des éléments d’information supplémentaires à une étiquette déjà visible à l’écran, l’utilisation de aria-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 du aria-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 valeur true ou false.

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.

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 de menubar.
  • 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, le menuitem est connu comme un menuitem parent. L’élément de menu d’un sous-menu est contenu dans ou appartient à son parent menuitem.
    Un menuitem parent a l’état aria-haspopup défini sur menu ou true.
  • Un menuitem parent a aria-expanded défini sur false lorsque son menu enfant n’est pas visible et défini sur true 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 sur 0.
  • 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ément menubar a une étiquette fournie par aria-label.

Voir aussi :

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.

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ôle tablist.
  • 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ément tabpanel associé.
  • L’élément d’onglet actif a l’état aria-selected défini sur true et tous les autres éléments d’onglet l’ont défini sur false.
  • Chaque élément ayant un rôle tabpanel a la propriété aria-labelledby en se référant à son élément tab associé.
  • Si l’élément tablist est orienté verticalement, la propriété aria-orientation est définie sur vertical. Notons que la valeur par défaut de aria-orientation pour un élément tablist est horizontale; il est donc inutile de le préciser si c’est le cas.

Voir aussi :

Boites de dialogue

Une boite de dialogue doit répondre aux conditions suivantes :

  1. Lorsqu’une boite de dialogue apparait, le focus doit y être déplacé.
  2. La boite de dialogue doit être identifée en tant que boite de dialogue avec un identifiant qui en indique la fonction.
  3. Tout le contenu de la page en dehors de la boite de dialogue doit être masqué pour les outils d’adaptation.
  4. La boite de dialogue doit pouvoir être fermée avec le bouton prévu à cet effet ou avec la touche Échappe.
  5. À la fermeture de la boite de dialogue, le focus doit être ramené à l’élément qui en a déclenché l’ouverture.

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 le role="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 sur true.
    (Voir la note à la fin de cette liste concernant aria-modal et aria-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ôle dialog 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.

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 de aria-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 sur true 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 sur true.

Voir aussi :

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 :

  1. Il doit être ouvert ou fermé à l’aide d’un bouton et non d’un lien.
  2. L’état doit être communiqué lorsque le focus atteint le bouton et tout changement d’état doit être immédiatement annoncé à l’utilisateur.
  3. 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.

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 a aria-expanded défini sur true. Si le panneau n’est pas visible, aria-expanded est défini sur false.
  • 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.

Voir aussi :

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.

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> avec aria-live défini à assertive afin que le lecteur d’écran lise le message d’erreur au moment où il apparaît.

Voir aussi :

Pour approfondir le sujet et comprendre comment utiliser correctement WAI-ARIA, vous pouvez vous référer aux sources suivantes (en anglais) :