Project

General

Profile

Anomalie #4543

Accessibilité des chargements ajax (live regions)

Added by nicod _ 7 months ago. Updated about 2 months ago.

Status:
Fermé
Priority:
Normal
Assignee:
Category:
accessibilité
Target version:
Start date:
09/02/2020
Due date:
% Done:

0%

Resolution:
fixed
Navigateur:

Description

Suite à un audit de site par Temesis, il remonte que les attributs aria qu'on utilise sont mal placés.

Je cite :

Il semble qu’il y a un problème plus global avec l’utilisation des live region :
Je rencontre à nouveau le div englobant div.ariaformprop qui possèdent les attributs

aria-live
aria-atomic
aria-relevant

Cette utilisation de ces attributs est erronée :

elle ne donne pas le résultat probablement attendu
le support d’aria-relevant dans les assistances technologiques n’est pas assuré

Il est donc nécessaire de ne pas utiliser de live region sur une div englobante comme là.
Il faut supprimer ces attributs et utiliser aria-live et aria-atomic avec parcimonie.

J'ai regardé l'exemple que tu donnes sur spip.net également.

L'exemple était : https://www.spip.net/spip.php?page=recherche&recherche=plugin&debut_articles=0#pagination_articles

Cette prolifération d'aria-live + aria-atomic part probablement d'un bon sentiment, mais comme parfois avec l'accessibilité, le mieux est l'ennemi du bien.

En positionnant ces attributs, avec ces valeurs, sur des div englobantes, cela génère dans les lecteurs d'écran la lecture automatique des contenus qui ont été mis à jour.

Certes la lecture peut être interrompue par l'utilisateur, mais cela revient, à mon avis à imposer quelque chose qui n'a pas été forcément souhaité. De cette manière le propriétaire du site impose une expérience différente aux utilisateurs de lecteur d'écran.
Ensuite, il faut bien entendu prendre en compte le contexte. Il pourrait arriver que ce comportement soit pertinent. Ce n'est pas le cas ici.

Dans le cas de rechargement ajax, il faut étudier chaque cas et son contexte, mais le plus souvent le principe est :

Ne pas utiliser ces attributs lorsqu'il n'y a pas d'interactions / rechargement ajax . Exemple sur un formulaire, cela n'a pas de sens : on rempli un form et puis on valide le form. A priori (si j'ai bien compris le fonctionnement) il n 'y a aucune raison d'utiliser de live region. En théorie, la présence de ces attributs s'il n'y a pas de rechargement ne devrait pas gêner. Mais certains lecteurs d'écran peuvent prendre des libertés par rapport aux spécifications et vocaliser des contenus tout de même. C'est pourquoi il faut être parcimonieux.

Lorsqu'ils sont utiles et nécessaires, utiliser ces attributs pour informer d'un changement. Exemple : donner le nouveau nombre de résultats après utilisation de filtre. Mais il faut bien penser que dans plusieurs cas ils ne sont pas nécessaires, en effet, un bouton d'action doit être explicite avant qu'on appuie dessus. Donc par exemple : lorsque je demande à afficher la page 2 dans une pagination de résultat, il n'y a pas d'info à vocaliser automatiquement, le fait que le bouton dise "afficher la page 2" est suffisant, il serait superflu, voire gênant d'aller plus loin dans ce qui est vocalisé.

Enfin, il faut gérer le focus clavier. Cet aspect est essentiel dès qu'il y a des interactions ajax, mais il dépend totalement du contexte. Et cet aspect est indépendant de la nécessité d'utiliser les live regions. Exemple : dans une série de filtre on va laisser le focus sur le filtre pour que l'utilisateur puisse parcourir la série de filtre. A contrario, dans une pagination (ou quand on a un bouton de type "afficher plus d'articles", dans des news ou dans une page de produits pour un site de e-commerce) on va déplacer le focus sur le 1er nouveau élément qui vient de s'afficher (la zone qui a été mise à jour).

History

#1 Updated by nicod _ 7 months ago

En résumé, ces attributs aria sont à supprimer de manière générale.

Dans le cas d'une pagination, ils seraient à placer sur le tag html qui indique le nombre de résultats, donc à placer manuellement dans les squelettes, au cas par cas.

#2 Updated by RastaPopoulos ♥ 7 months ago

En positionnant ces attributs, avec ces valeurs, sur des div englobantes, cela génère dans les lecteurs d'écran la lecture automatique des contenus qui ont été mis à jour.

Certes la lecture peut être interrompue par l'utilisateur, mais cela revient, à mon avis à imposer quelque chose qui n'a pas été forcément souhaité. De cette manière le propriétaire du site impose une expérience différente aux utilisateurs de lecteur d'écran.

Je ne suis pas sûr de comprendre : lancer la lecture des contenus mis à jour c'est bien très exactement ce qu'on cherchait à faire avec ces attributs il me semble. Donc ça fait bien ce qu'on cherche à faire. À la louche, je pense que 99% des utilisations de rechargement ajax SPIP (avec le critère {ajax} + des liens ".ajax" ou des forms) concernent parfaitement des cas avec une interaction donc un rechargement qui est explicitement demandé par l'utilisateurice : clic sur un lien qui recharge un bloc ajax OU clic sur un bouton qui recharge un formulaire en ajax. Ce n'est donc pas du tout quelque chose d'imposé et de forcé : l'utilisateurice demande une ressource (lien ajax) ou poste un formulaire (ajax) qui sont alors chargés dynamiquement SANS recharger toute la page : on veut donc bien effectivement que le lecteur d'écran se mette à relire le morceau qui vient d'être chargé !

Ne pas utiliser ces attributs lorsqu'il n'y a pas d'interactions / rechargement ajax . Exemple sur un formulaire, cela n'a pas de sens : on rempli un form et puis on valide le form. A priori (si j'ai bien compris le fonctionnement) il n 'y a aucune raison d'utiliser de live region.

Ces attributs sont sur des forms ajax, pas les forms non-ajax, non ? Quand on poste un formulaire ajax, alors seulement son bloc se recharge, et à l'intérieur de ce bloc, les contenus ont changé : des erreurs sont affichés, ou un message de retour final est ajouté, etc. C'est donc bien totalement voulu (l'utilisateurice a volontairement cliqué) et on veut que ça relise ce morceau puisque des contenus ont changé dedans, et souvent très important pour un formulaire (erreurs à corriger etc).

Du coup je ne comprends pas leurs remarques : on a l'impression que tout ce qu'ils disent part du principe que ce sont des choses rechargées en arrière-plan par une volonté du dév (ce qui peut arriver dans 1% des cas, super rare), alors que non non, c'est bien à chaque fois un clic volontaire (lien ou bouton) de l'utilisateurice.

#3 Updated by nicod _ 7 months ago

Réponse à tes remarques que j'ai faites remonter :

J’ai bien compris que c’est l’utilisateur qui déclenche explicitement les modifications via lien ou bouton.
Je comprends le besoin d'avoir des paramètres qui gèrent automatiquement la génération de ces attributs.

Et tu l'as dit toi-même :

Dans les faits, on ne peut donc pas du tout présumer de ce qui est chargé en ajax de façon générique, ça peut être une liste avec pagination, mais ça peut être aussi un fragment de html qui se recharge en fonction d'autres évènements, ou même une page où différents blocs sont chargés en ajax (asynchrone) et ne sont pas modifiés ensuite.

Donc en pratique, sans connaître les contenus et les interactions utilisateur/contenus on ne peut pas savoir si c'est une bonne chose ou pas d'avoir ces attributs.
La solution qui consiste à les positionner sur des éléments englobants, sauf coup de chance involontaire, sera mauvaise.
Sur le site de la région c'est flagrant.
Par ailleurs, je ne connais pas les compétences en accessibilité numérique des personnes qui te répondent.
En l'occurrence, les réponses semblent indiquer que les personnes en question ne maîtrisent pas vraiment :

le fonctionnement des live region et leur raison d’être
le fonctionnement des lecteurs d'écran
la différence entre ce qui est vocalisé dans un lecteur d'écran, la position du focus clavier et la position du curseur du lecteur d’écran
l’utilisation des lecteurs d’écran

La phrase "lancer la lecture des contenus mis à jour c'est bien très exactement ce qu'on cherchait à faire avec ces attributs" montre qu’il s’agit d’une mauvaise utilisation des propriétés aria-live et semble démontrer une connaissance très limitée des 4 points cités plus haut.

Personnellement, je n'ai pas les compétences suffisantes sur ces 4 points pour avoir un avis, je me fie à celui de l'expert, qui est de simplement supprimer les attributs aria.
Par contre, je sais par expérience que aria n'est pas facile à utiliser, et qu'il vaut mieux ne pas l'utiliser que mal l'utiliser.

#4 Updated by RastaPopoulos ♥ 7 months ago

Moi j'ai pas participé à ces ajouts hein mais j'essaye de comprendre.

On est d'accord que aria-live=polite, ça fait que lorsque l'utilisateur ne fait rien d'important (le polite), alors ça va relire le morceau qui a été "actualisé en live", s'il a changé ? c'est bien ça ?

Ce que je dis c'est que 99% des utilisations de l'ajax de SPIP, concernent effectivement un cas où l'utilisateurice a cliqué volontairement et s'attend donc à ce que ça lui lise ce qui vient de changer (et c'est bien le bloc parent entier que SPIP recharge, quel est le problème ?).

Si sur le site de cette région, ya pas mal d'ajax qui se recharge "tout seul" sans interaction, possible oui ça va pas du tout, mais ce n'est vraiment pas le plus courant dans l'utilisation classique de SPIP, et il me semblait que vu la proportion, c'était plutôt bien si par défaut ça relisait le bloc rechargé (volontairement par un clic, dans l'immense majorité des cas).

Mais du coup on parle que théoriquement, et sûrement que je pige pas du tout oui… il faudrait plutôt parler sur des cas concrets (genre tel bloc ajax de telle page avec une pagination qu'on clique volontairement et qui recharge alors telle portion de la page).

En tout cas cette utilisation (majoritaire encore une fois) semblait correspondre à la doc de base (sur MozDev par ex) :

Normalement, seul aria-live="polite" est utilisé. Toute zone recevant une mise à jour qu’il est important de faire suivre à l’utilisateur, mais pas au point de le déranger dans sa navigation, devrait recevoir cet attribut. Le lecteur d’écran lira les changements dès que l’utilisateur sera inoccupé.

Si ça reste par défaut, peut-être qu'il faudrait un critère pour ne pas générer ces attributs quand on sait qu'il va s'agir d'un bloc ajax rechargé automatiquement, non volontairement ?

#5 Updated by nicod _ 7 months ago

Si sur le site de cette région, ya pas mal d'ajax qui se recharge "tout seul" sans interaction, possible oui ça va pas du tout,

Non non, ce sont les cas classiques d'utilisation "de base" : formulaires, et listes de résultats avec paginations.

#6 Updated by RastaPopoulos ♥ 7 months ago

Ok ok, bon bah je pige vraiment rien donc :D

Vu que ça correspond exactement à la doc et même aux divers exemples un peu concrets donnés sur MozDev par ex de quand utiliser ça, des cas d'utilisation où c'est utile voire important de le mettre.

Genre

Un site web spécialisé dans l’ornithologie fournit une liste avec des noms d’oiseaux. Lorsqu’un oiseau est sélectionné dans la liste, une zone de la page web est actualisée avec les détails concernant la famille d’oiseaux choisie.
Lorsque l’utilisateur sélectionne un nouvel oiseau, l’information est lue [par le lecteur d'écran].

Quand au "div englobant" je ne pige pas non plus la remarque vu que c'est pas juste "le div englobant" : c'est précisément de div, ce bloc, qui est rechargé en ajax, donc dans les cas où c'est pertinent de faire lire au lecteur ce qui vient d'être rechargé, bah c'est bien effectivement ce bloc qui doit avoir la propriété puisque c'est ça qui est rechargé.

#7 Updated by nicod _ 7 months ago

Je viens d'avoir une confirmation par une autre experte accessibilité qu'il faut supprimer ces attributs : https://mamot.fr/@lena/104822641354406079

La subtilité serait donc éventuellement de placer aria-live="polite" sur le premier résultat lors d'une pagination uniquement.

#8 Updated by nicod _ 7 months ago

  • Target version set to 3.3

#9 Updated by RastaPopoulos ♥ 7 months ago

Mmh pour le polite, elle dit pas de le supprimer tout court donc, mais le supprimer de cet endroit et le déplacer à un autre… Donc l'idée ça serait que c'est au final à chacun⋅e de le placer sur un élément au début de l'intérieur de ce qu'on recherche… si c'est pertinent pour ce cas de rechargement. Le "problème" étant que c'est effectivement pertinent d'après ce que je comprends dans 99% (allez 90% pour être gentil) des utilisations d'ajax de SPIP, liens et forms compris (sur 100% des forms déjà, quand on les recharge en ajax, c'est volontaire, et on veut que ça lise le début du bloc rechargé, indiquant qu'il y a XX erreurs par ex ou inverse que tout s'est bien passé). Mais donc ça veut dire qu'il faudrait reprendre des centaines de squelettes pour ajouter cet attribut au début de chaque morceau rechargé, manuellement… :(

Au-delà de la recommandation, l'explication précise c'est quoi derrière ? Quand l'attribut est sur le parent, ça fait que le bloc rechargé entier est lu (sans pouvoir être arrêté ?) par le lecteur ? Alors que si on met l'attribut que sur un premier élément au début de l'intérieur du bloc, alors seul cet élément est relu et ça laisse le focus du lecteur à cet endroit ?

Ça serait bien de savoir concrètement ce que ça veut dire, ce que ça produit comme effet, et donc pourquoi on conseille de pas le mettre sur le div du bloc rechargé entier mais seulement sur un élément du début interne.

Surtout que ces conseils sont inverses à ce qui est documenté sur MozDev, qui dans ses exemples de l'attribut "polite" (comme pour les fiches oiseaux cités plus haut) met bien l'attribut sur le bloc rechargé entier.

#10 Updated by RastaPopoulos ♥ 7 months ago

Ah là ya un peu d'explication :
https://disic.github.io/guide-developpeur/9-utiliser-aria.html

Bien utilisée, cette propriété est une solution robuste et efficace pour gérer les zones de mise à jour dynamique, par exemple un panier d'achats affiché dans la page.

Mais attention : puisque la zone contrôlée par aria-live va être vocalisée, il convient de l'utiliser avec précaution dès que cette zone va contenir beaucoup de contenus.

Par exemple, imaginons un moteur de recherche qui afficherait ses résultats dans la même page via AJAX. L'utilisation de aria-live sur la zone mise à jour risque d'être particulièrement lourde et contre-indiquée. Préférez une prise de focus sur la zone mise à jour en résultat de la fonctionnalité de recherche afin de simuler un rechargement de page classique par exemple.

Donc pour tout rechargement ajax suite à un clic (liens rechargeant un bloc, ou validation de formulaire), il faudrait retirer l'attribut et "juste" placer le focus au début du bloc. Est-ce déjà le cas aussi ?

#11 Updated by nicod _ 7 months ago

Au-delà de la recommandation, l'explication précise c'est quoi derrière ? Quand l'attribut est sur le parent, ça fait que le bloc rechargé entier est lu (sans pouvoir être arrêté ?) par le lecteur ?

C'est ce que j'en ai compris, de mon côté j'ai du mal à tester, je n'ai que VoiceOver sur Safari, il faudrait que j'arrive à installer JAWS.

Donc pour tout rechargement ajax suite à un clic (liens rechargeant un bloc, ou validation de formulaire), il faudrait retirer l'attribut et "juste" placer le focus au début du bloc. Est-ce déjà le cas aussi ?

C'est bien ce que je comprends des recos, oui, attribut aria sur le premier résultat et redonner le focus sur cet élément.

C'est peut être automatisable en JS, si on détecte qu'il y a une pagination avec $('.pagination).length, pour placer dynamiquement l'attribut et le focus depuis un ajaxLoad().

#12 Updated by nicod _ 7 months ago

nicod _ a écrit :

C'est bien ce que je comprends des recos, oui, attribut aria sur le premier résultat et redonner le focus sur cet élément.

J'ai dit une bêtise : retirer l'attribut aria-live et juste gérer le focus.

Précisions :

(D'ailleurs, pour effectuer cela, afin de donner le focus à un élément qui normalement ne le reçoit pas, il faut lui ajouter un attribut tabindex="-1".)
Enfin, il est vraiment important de voir en contexte leur nécessité, si je reprend l'exemple donné sur le github de la disic, à propos d'un panier d'achats, ce n'est pas aussi simple qu'ils l'ont écrit. Tout va dépendre du comportement global. Exemples, après avoir mis un article dans le panier :

- je suis redirigé vers la page du panier s'affiche (rechargement de page) > alors pas d'aria-live
je reste sur ma page produit et une "animation" montre mon article qui va dans le panier où le nombre d'article est incrémenté > là on utilise une live region qui va dire un truc du style "3 articles dans le panier" (ou qui peut être plus précise même : "l'article "x" a été ajouté, vous avez 3 articles dans le panier")
- le panier s'affiche comme une modale (souvent c'est un panneau à droite de l'écran) -> là non plus, a priori pas d'aria-live nécessaire, comme il y a forcément une gestion du focus à prévoir pour amener l'utilisateur dans la bonne zone, on va donner le focus à un titre du style "votre panier (3 articles)"
etc.

#13 Updated by nicod _ 7 months ago

Pour info, mon interlocuteur sur ces questions, que je cite, est Eric Gateau, de Temesis (https://temesis.com/a-propos/equipe-temesis/) avec qui je collabore sur un projet en ce moment.

#14 Updated by cedric - about 2 months ago

  • Status changed from Nouveau to En cours
  • Assignee set to cedric -

#15 Updated by cedric - about 2 months ago

  • Status changed from En cours to Fermé
  • Resolution set to fixed

Also available in: Atom PDF