Normes · WCAG 2.2

SC 4.1.3 Niveau AA WCAG 2.1

Messages de statut

Les messages de statut — confirmations, erreurs, mises à jour de progression, nombre de résultats — doivent être annoncés aux technologies d'assistance sans déplacer le focus. Utiliser role=status, role=alert ou aria-live sur une région déjà présente dans le DOM.

Ce que ce critère demande

Lorsque la page informe l’utilisateur qu’une action s’est produite — « Article ajouté au panier », « 3 résultats trouvés », « Connexion perdue », « Enregistrement en cours… » — ce message doit parvenir aux utilisateurs de lecteurs d’écran sans forcer le déplacement du focus. L’information doit être déterminée programmatiquement comme un statut, afin que la technologie d’assistance puisse la récupérer et l’annoncer.

WCAG distingue trois catégories :

  • Succès / achèvement — « Profil enregistré », « E-mail envoyé ».
  • Résultats d’une action — « 12 résultats », « Aucune correspondance trouvée ».
  • État de l’application — « Enregistrement en cours… », « Reconnexion », « Chargement 40 % ».

Comment le satisfaire

  • Placer une région dynamique dans le DOM au chargement de la page — un élément vide avec role="status" (poli) ou role="alert" (assertif). Lors d’une mise à jour, injecter le nouveau texte à l’intérieur.
  • Pour les confirmations non critiques et les comptages de résultats, utiliser role="status" ou aria-live="polite". Les lecteurs d’écran attendent que l’utilisateur soit inactif, puis annoncent.
  • Pour les messages critiques — erreurs de soumission de formulaire, perte de connexion, session sur le point d’expirer — utiliser role="alert" ou aria-live="assertive". L’annonce interrompt la lecture en cours.
  • Les notifications toast ont besoin d’une région dynamique. Le conteneur de toast doit exister dans le DOM avant l’apparition du toast, avec aria-live défini, et le texte du toast injecté en tant qu’enfant.
  • Associer aria-live à aria-atomic="true" si l’on souhaite que toute la région soit relue à chaque mise à jour, et non seulement les nœuds modifiés.
  • Pour les erreurs de formulaire, le message d’erreur en ligne peut utiliser role="alert", ou le focus peut être déplacé vers un récapitulatif en haut du formulaire — mais il ne faut pas faire les deux ; l’utilisateur n’a besoin d’entendre le message qu’une seule fois.

Échecs courants

  • Les notifications toast rendues dans un élément qui n’existait pas avant l’apparition du toast — l’écouteur de région dynamique ne s’attache jamais, rien n’est annoncé.
  • Une bannière de succès insérée en dehors de toute région aria-live — visible pour les utilisateurs voyants, invisible pour les utilisateurs de lecteurs d’écran.
  • Le comptage de résultats de recherche (« Affichage de 12 sur 340 ») qui se met à jour silencieusement après filtrage. Les utilisateurs reviennent dans les résultats sans savoir si quelque chose a changé.
  • La validation de formulaire qui met à jour un <span class="error"> en ligne sans role="alert" ni aria-live — l’erreur apparaît, le lecteur d’écran reste silencieux.
  • L’utilisation de aria-live="assertive" pour chaque mise à jour de statut. Interruptions constantes ; les utilisateurs de lecteurs d’écran désactivent la page.
  • Le déplacement du focus vers un message de statut qui n’est ni un en-tête ni un élément interactif — le focus atterrit sur un élément non focalisable, les utilisateurs au clavier perdent leur position.
  • Les indicateurs « Enregistrement en cours… » / « Enregistré » qui changent une classe CSS mais ne mettent jamais à jour le contenu textuel à l’intérieur d’une région dynamique.

Pourquoi c’est important

Les messages de statut sont le point de défaillance des applications web monopage modernes. La page ne se recharge jamais, le focus se déplace rarement, et le seul signal pour l’utilisateur qu’une action s’est produite est un changement visuel — inutile pour quiconque ne regarde pas l’écran. Le critère 4.1.3 impose la parité : si un utilisateur voyant peut voir « Ajouté au panier », un utilisateur de lecteur d’écran peut l’entendre. La correction est presque toujours peu coûteuse (une région dynamique, alimentée lors de la mise à jour) et son absence brise presque toujours des parcours essentiels — achat en ligne, recherche, soumission de formulaire, chat en temps réel.