Identifiants ambigus : simple observateur inoffensif ou reine du chaos ?
Un peu de contexte
Les identifiants en double constituent l’une des violations les plus courantes de la directive WCAG 4.1.1 signalées par les outils de test d’accessibilité automatisés tels qu ’axe, et cela peut causer pas mal de problèmes à vos utilisateurs. Ce problème survient lorsque plusieurs éléments d’une page web possèdent le même attribut « ID ». On me demande souvent comment ces identifiants ambigus, en apparence anodins, peuvent causer autant de problèmes.
La réponse est simple : comme pour tant d’autres questions d’accessibilité et d’ergonomie, tout dépend vraiment du contexte et de la manière dont les attributs « id » sont utilisés. Parfois, l’utilisation d’attributs « id » non uniques peut avoir des conséquences désastreuses, non seulement en termes d’accessibilité, mais aussi d’ergonomie. Je vais vous montrer comment dans cet exemple.
Exemple 1 – Mec, c'est quelle carte bancaire que j'ai utilisée ?
La situation suivante ne s'est pas produite « Il y a très très longtemps, dans une galaxie très très lointaine ». Elle s'est produite sur une véritable page web d'une véritable entreprise.
À l'aide de votre souris, essayez de cliquer sur la deuxième ou la troisième étiquette du formulaire (« Carte se terminant par 9892 » ou « Carte se terminant par 2388 ») :
Q : Quelle case a été cochée ?
R : Probablement la première case à cocher (« Carte se terminant par 4499 »).
Attends un peu. Qu'est-ce qui s'est passé ?
Dans ce formulaire, les libellés sont explicitement associés à leurs cases à cocher (la valeur de l’attribut du libellé correspond à l’ID de la case à cocher). Lorsqu’elle est correctement mise en œuvre, cette approche garantit à la fois l’accessibilité et la facilité d’utilisation. Lorsqu’un libellé est spécifiquement associé à un champ de formulaire, les utilisateurs peuvent cliquer dessus avec la souris pour interagir avec ce champ. Par exemple, ils peuvent cocher ou décocher une case à cocher ou un bouton radio, ou encore déplacer le focus vers un champ de saisie de texte. Cette zone cliquable agrandie profite à de nombreux utilisateurs, comme les personnes âgées malvoyantes ou celles dont la motricité fine est limitée. Elle est également utile pour Monsieur Tout-le-monde (ou Madame Tout-le-monde), tout simplement parce qu’elle est plus facile à voir et à utiliser.
Mais dans notre exemple, toutes les cases à cocher avaient le même identifiant. Ce code HTML n' est pas valide et le navigateur doit faire de son mieux pour pallier ce problème. La plupart des navigateurs recherchent le premier élément du DOM dont l'identifiant correspond à celui spécifié dans l'attribut « for » de l'élément `label`. L'élément `label` est alors associé à cet élément.
C'est ainsi que les trois étiquettes se retrouvèrent toutes associées à la première case à cocher. Les autres cases à cocher furent laissées pour compte, vides et sans nom.
Mais quand je clique directement sur la case à cocher ou que je la coche avec la barre d'espace, tout fonctionne parfaitement !
Lorsque vous interagissez directement avec le contrôle, le navigateur n'a pas besoin de deviner quelle case à cocher vous souhaitiez sélectionner.
Je comprends qu'il s'agit d'un problème d'ergonomie. Mais en quoi est-ce un problème d'accessibilité ?
On dit souvent que l'accessibilité, c'est l'ergonomie à un niveau supérieur. Et voici pourquoi :
Les utilisateurs d'applications d'assistance, telles que les lecteurs d'écran, s'appuient bien davantage sur les associations programmatiques que les utilisateurs lambda. Ne pouvant pas voir l'écran, l'emplacement visuel, la proximité et les repères visuels ne leur sont guère utiles.
Lorsqu'un utilisateur de lecteur d'écran déplace le focus sur un champ de formulaire, le lecteur d'écran doit annoncer le nom accessible de ce champ. Le lecteur d'écran recherche l'étiquette associée au champ de formulaire et annonce le contenu textuel de cette étiquette comme étant le nom accessible du champ de formulaire.
Dans mon exemple, le lecteur d'écran est déconcerté. Lorsque l'utilisateur place le focus sur la première case à cocher, il trouve non pas une, mais trois étiquettes qui lui sont associées. La plupart des lecteurs d'écran regroupent le contenu textuel de ces étiquettes en une seule chaîne de caractères et annoncent cette chaîne comme étant le nom accessible de la case à cocher.
J'ai testé cet exemple en utilisant NVDA 2023.1 et Jaws 2023 avec Chrome 116.0.5845.97.
La première case à cocher est annoncée ainsi par les deux lecteurs d'écran :« Carte se terminant par 4499, Carte se terminant par 9892, Carte se terminant par 2388, case non cochée ».
La situation est encore plus confuse pour les cases à cocher n° 2 et n° 3. JAWS et NVDA ne fournissent pas de nom accessible pour ces cases à cocher. L'utilisateur d'un lecteur d'écran n'a d'autre solution que de cocher une case au hasard, en espérant que les informations relatives à la carte seront révélées plus tard dans le processus.
Alors, quelle est l'ampleur de ce problème ?
Si votre client sélectionne par erreur une carte bancaire qui n'est pas la bonne pour régler une facture, cela signifie qu'il finira par effectuer une transaction financière qu'il n'avait pas l'intention d'effectuer, ce qui pourrait nuire à la relation client.
Bien sûr, vous pouvez remédier en partie à ce problème potentiel en respectant le critère de succès 3.3.4 des WCAG, ce qui permettrait au client de confirmer ou de corriger ses données. Mais en fin de compte, il vaudrait mieux éviter que ce genre d'incident ne se produise dès le départ.
Exemple n° 2 – les lecteurs d'écran qui racontent n'importe quoi.
Parfois, l'accessibilité exige des développeurs qu'ils exposent par programmation une relation entre les éléments d'une page Web aux technologies d'assistance. Un cas de figure courant se présente lorsque des instructions sont associées à un champ de formulaire. Visuellement, cela s'obtient en plaçant l'élément contenant le texte d'instruction à proximité du champ de formulaire à l'écran, ou en affichant le contenu de l'instruction sous forme d'info-bulle lorsque l'utilisateur passe la souris sur le champ de formulaire ou y place le focus. Cependant, les lecteurs d'écran ne sont pas en mesure de communiquer cette information sans balisage supplémentaire.
Pas d'inquiétude ! Nous pouvons facilement ajouter le balisage nécessaire à l'aide de l'attribut `aria-describedby`. Cet attribut s'applique au champ de formulaire et sa valeur correspond à l'identifiant (ou à une liste d'identifiants séparés par des espaces) du ou des éléments que les lecteurs d'écran doivent annoncer lorsque l'utilisateur place le curseur sur le champ de formulaire.
Nous en revenons donc aux attributs ID. Que doit faire le lecteur d'écran si la valeur de l'attribut `aria-describedby` renvoie à un ID utilisé par plusieurs éléments ?
Problèmes avec les indications pour les lecteurs d'écran.
J'ai ajouté ici des infobulles utiles pour les deux champs du formulaire, mais d'une manière qui ne sera pas compréhensible pour les utilisateurs de lecteurs d'écran.
- The <span> elements containing the hints have the same ID attribute:
id="hint". - Les deux champs du formulaire renvoient vers leurs éléments d'aide à l'aide de
aria-describedby="hint".
Ce code HTML n'est pas valide, même si cela ne devrait concerner que les utilisateurs de technologies d'assistance.
Comment les lecteurs d'écran vont-ils gérer ce fouillis ?
En effectuant un test avec la même combinaison que dans le premier exemple, j'ai concentré mon attention sur le champ de saisie du numéro de téléphone. Devinez ce que j'ai entendu ?
- JAWS : « Veuillez saisir votre numéro de téléphone, edit. Vous ne pouvez utiliser que des lettres et des espaces, pas de chiffres s'il vous plaît... »
- NVDA : « Veuillez saisir votre numéro de téléphone, modifier. Vous ne pouvez utiliser que des lettres et des espaces, pas de chiffres s'il vous plaît... »
Oh oh. Les deux lecteurs d'écran recherchent la première occurrence de l'ID référencé et lisent à voix haute le contenu textuel de cet élément.
C'est ainsi que tous les utilisateurs de lecteurs d'écran du pays reçurent pour consigne de saisir leur numéro de téléphone en n'utilisant que des lettres ou des espaces.
Alors, à quel point le problème des identifiants non uniques est-il grave ?
Récapitulons.
Si les identifiants ne sont pas utilisés par des attributs ou des scripts sur votre page Web, il y a de fortes chances qu'ils n'aient aucune incidence sur l'accessibilité de celle-ci. Mais dès qu'un attribut « id » est utilisé pour établir une relation programmatique sur votre page Web, cela commence à avoir des répercussions sur vos utilisateurs.
Il existe de nombreuses situations dans lesquelles les identifiants sont utilisés pour assurer certaines fonctionnalités sur les pages Web. Je n'ai cité ici que deux des cas les plus courants.
Outre le fait qu'ils fournissent un contexte programmatique, comme illustré ici, les attributs « id » peuvent servir de cibles pour les sélecteurs JavaScript ou CSS. Faites preuve d'imagination pour envisager la multitude de scénarios pouvant se présenter lorsque vos sélecteurs ne fonctionnent pas comme prévu.
J’ai pris l’exemple d’un utilisateur de lecteur d’écran pour illustrer le problème, mais de nombreuses autres technologies d’assistance, telles que les logiciels de reconnaissance vocale et les agrandisseurs d’écran, exploitent les relations programmatiques entre les éléments d’une page web. À mesure que les solutions d’assistance se généralisent (comme c’est le cas pour les solutions de navigation web à commande vocale destinées aux voitures), il est probable que le nombre d’utilisateurs comptant sur le caractère unique de vos attributs ID augmente.
Que dois-je faire ?
N'oubliez pas : un élément d'une page web dispose de certains droits inaliénables ; le fait de posséder un identifiant unique en fait partie.
Prévenez l'usurpation d'identité des éléments HTML en veillant à ce que chaque élément de votre page Web nécessitant un identifiant en possède un unique.
Cela évitera bien des maux de tête à vos utilisateurs et réduira le risque de semer la confusion chez votre équipe du service client. Cela permettra également de limiter les cas de frustration chez les développeurs et, dans les cas les plus graves, les dégâts causés au mobilier de bureau. 🙂
*Nous tenons à remercier tout particulièrement Birkir Gunnarson pour ses contributions antérieures à cet article.