Technique28 juillet 202616 min

aria-live et messages de statut : comprendre le critère RGAA 7.5

En Bref : L'essentiel à retenir

  • Le critère RGAA 7.5 (niveau AA, WCAG 4.1.3) exige que les messages de statut soient restitués aux technologies d'assistance sans prendre le focus.
  • Règle de pré-existence : une région live doit exister vide dans le DOM avant l'insertion du message, sinon elle reste muette (cause numéro un d'échec).
  • role="status" (poli, n'interrompt pas) pour succès, résultat ou état ; role="alert" (assertif, interrompt) pour erreurs et urgences ; progression via role="log", role="progressbar" ou role="status".
  • Les erreurs de saisie de formulaire relèvent des critères 11.1, 11.10 et 11.11, pas du 7.5.
  • 7.5 est un critère à vérification manuelle : sur 106 critères RGAA, RGAA Checker en vérifie 8 automatiquement, en pré-vérifie 65 et en laisse 33 manuels ; il émet un signal « à vérifier », jamais un verdict de conformité.
RGAAARIAScriptsDéveloppementAccessibilité

Le compteur de votre panier passe de 1 à 2 articles. Un toast « Message envoyé » apparaît en bas de l'écran. Les résultats de recherche se filtrent en direct pendant que l'internaute tape. Pour une personne voyante, ces micro-changements sont évidents : l'œil les capte au passage, sans quitter la tâche en cours. Pour une personne aveugle qui navigue au lecteur d'écran, ils sont tout simplement silencieux, sauf si le développeur a pensé à les annoncer via une région live. C'est exactement le rôle du critère RGAA 7.5.

Ce critère est l'un des plus mal compris du référentiel : on confond role="status" et role="alert", on croit qu'une région aria-live suffit à tout, on range à tort les erreurs de formulaire sous 7.5, et on tombe sur le piège du timing qui rend une région pourtant présente totalement muette. Cet article reprend le sujet au niveau du critère : les trois tests officiels, l'arbre de décision entre statut poli et alerte assertive, la règle de pré-existence dans le DOM, la démarcation avec les erreurs de saisie, et ce qu'un scanner peut réellement voir (ou pas).

Qu'est-ce qu'un message de statut ?

Le glossaire officiel de la DINUM (accessibilite.numerique.gouv.fr) définit un message de statut comme un message qui « informe l'utilisateur d'un changement de contenu dans la page sans interrompre son activité principale (il n'y a pas de changement de contexte, par exemple un repositionnement du focus sur le message) ». La partie importante est là : le message informe sans déranger, et surtout sans prendre le focus.

Les quatre types de messages de statut

Le référentiel liste quatre familles de messages concernées :

  • Réussite ou résultat d'une action : « Article ajouté au panier », « Formulaire envoyé », « 5 résultats trouvés ».
  • État occupé de l'application : « Chargement en cours », « Enregistrement… ».
  • Progression d'un processus : téléversement à 40 %, étape 2 sur 4.
  • Existence d'une erreur : « L'adresse e-mail est invalide » (hors validation de champ de formulaire, nuance détaillée plus bas).

Un message de statut n'est pas un changement de contexte

Le glossaire distingue explicitement le changement de contenu du changement de contexte. Un changement de contexte, ce sont des « changements majeurs dans le contenu d'une page web qui, s'ils sont faits sans que l'utilisateur n'en soit conscient, peuvent désorienter l'utilisateur ». Ouvrir une modale, changer de page, déplacer le focus : ce sont des changements de contexte, couverts par le critère 7.4 (« Pour chaque script qui initie un changement de contexte, l'utilisateur est-il averti ou en a-t-il le contrôle ? »).

Un message de statut est l'inverse : il ne doit pas prendre le focus. Si votre notification vole le focus au clavier, vous n'êtes plus dans le 7.5, vous créez un changement de contexte potentiellement non maîtrisé. Cette frontière est particulièrement sensible dans les applications React ou Vue où l'on gère le focus à chaque changement de route. Le sujet est traité en détail dans notre article sur l'accessibilité des SPA React et Vue et la gestion du focus.

Ce que le critère RGAA 7.5 exige

Voici le libellé officiel, verbatim :

Critère 7.5 (niveau AA, thème Scripts) : « Dans chaque page web, les messages de statut sont-ils correctement restitués par les technologies d'assistance ? »

Le critère 7.5 est de niveau AA et correspond au critère de succès WCAG 2.1 · 4.1.3 Status Messages. Il se décline en trois tests, chacun couvrant un type de message :

TestType de messageAttribut attendu
7.5.1Réussite, résultat ou état de l'applicationrole="status" ou aria-live="polite" + aria-atomic="true"
7.5.2Suggestion ou existence d'une erreurrole="alert" ou aria-live="assertive" + aria-atomic="true"
7.5.3Progression d'un processusrole="log", role="progressbar" ou role="status"

Notez le « ou » de chaque test : vous pouvez utiliser un rôle WAI-ARIA (qui porte les valeurs aria-live et aria-atomic de façon implicite), ou un aria-live explicite, mais dans ce dernier cas aria-atomic="true" est exigé. Ce détail est la source d'une bonne partie des échecs. Le libellé complet de chaque test figure sur la fiche du critère 7.5 de notre guide RGAA.

Ce qu'un lecteur d'écran ne perçoit jamais sans région live

Sans région live correctement câblée, tout changement de contenu injecté en JavaScript après le chargement reste invisible pour les technologies d'assistance. Le lecteur d'écran a déjà « lu » la page ; il ne relit pas spontanément ce qui change ensuite. Voici cinq situations, directement inspirées des exemples officiels de WCAG 4.1.3, qui restent muettes par défaut :

  • Le compteur de panier qui passe de « 1 » à « 2 » après un ajout.
  • Le nombre de résultats d'une recherche filtrée en direct (« 5 résultats »).
  • Le toast de succès après l'envoi d'un formulaire (« Votre message a bien été envoyé »).
  • L'état de chargement ou l'indicateur « en cours » pendant une requête.
  • Le message d'erreur affiché dynamiquement après une action.

Dans chacun de ces cas, la personne voyante voit le changement, la personne au lecteur d'écran n'entend rien, à moins que le message n'apparaisse dans une région live valide.

role="status" ou role="alert" : poli ou assertif ?

Le cœur du 7.5, c'est choisir le bon niveau d'urgence. Deux rôles couvrent l'immense majorité des cas.

role="status" : l'annonce polie

Un élément avec role="status" porte un aria-live="polite" et un aria-atomic="true" implicites. « Poli » signifie que l'annonce attend une pause dans la synthèse vocale : elle n'interrompt pas ce que la personne est en train d'écouter. C'est le choix par défaut pour un succès, un résultat ou un état, c'est-à-dire tout ce qui est utile mais non urgent.

CODE
<!-- Conteneur poli présent dès le chargement de la page -->
<div id="panier-status" role="status"></div>

<script>
  // Mise a jour : annoncee poliment, sans couper l'utilisateur
  document.getElementById('panier-status').textContent =
    'Article ajoute au panier (2 articles)';
</script>

role="alert" : l'annonce assertive

Un élément avec role="alert" porte un aria-live="assertive" et un aria-atomic="true" implicites. « Assertif » signifie que le lecteur d'écran interrompt la synthèse en cours pour annoncer le message immédiatement. Réservez-le aux erreurs et aux situations urgentes (champ invalide, session qui expire, connexion perdue). Pour tout ce qui touche aux subtilités de role="alert", notre article dédié ARIA alert : notifier les utilisateurs de lecteurs d'écran approfondit les cas d'usage et les limites.

CODE
<!-- Conteneur assertif present au chargement -->
<div id="form-status" role="alert"></div>

<script>
  // Injection du texte : le lecteur d'ecran interrompt et annonce
  document.getElementById('form-status').textContent =
    'Erreur : l\'adresse e-mail est invalide';
</script>

Le composant alerte lui-même fait l'objet d'une fiche de référence, Alerte accessible, qui en précise les critères RGAA et les pièges de restitution.

Progression : log, progressbar ou status

Le test 7.5.3 accepte trois attributs pour la progression d'un processus : role="log" (pour un flux de messages qui s'ajoutent, comme un chat), role="progressbar" (pour une barre chiffrée), ou role="status" (pour un état ponctuel). Le choix dépend de la nature de l'information affichée.

Tableau de décision

Type de messageRôle recommandéComportement
Réussite, résultat, état de l'applicationrole="status"Poli, n'interrompt pas
Suggestion, existence d'une erreur, urgencerole="alert"Assertif, interrompt
Progression d'un processusrole="log", role="progressbar" ou role="status"Selon le contexte

Le piège du timing : une région injectée avec son message ne parle pas

C'est la cause numéro un des échecs réels du 7.5, et elle surprend presque tout le monde. Une région live n'annonce pas son contenu initial : elle annonce les changements de son contenu. Le navigateur et le lecteur d'écran doivent d'abord « surveiller » un conteneur existant, puis détecter une modification.

Le mauvais pattern

Créer un élément déjà rempli et l'insérer dans le DOM ne déclenche aucune annonce, parce que, du point de vue du lecteur d'écran, il n'y a pas eu de changement de contenu : l'élément est arrivé complet.

CODE
<!-- A EVITER : la region est creee deja remplie, puis inseree -->
<script>
  const div = document.createElement('div');
  div.setAttribute('role', 'alert');
  div.textContent = 'Erreur : e-mail invalide'; // <- deja rempli
  form.appendChild(div); // <- souvent aucune annonce
</script>

La documentation MDN est catégorique sur ce point : « Do not try to dynamically add/generate an element with role="alert" that is already populated with the alert message you want announced. This generally does not lead to an announcement, as it is not a content change. » (source : MDN, référence du rôle alert).

Le bon pattern

Le conteneur vide doit exister dans le DOM au chargement de la page (il « amorce » la surveillance), puis on injecte seulement le texte.

CODE
<!-- RECOMMANDE : conteneur vide present au chargement -->
<div id="form-status" role="alert"></div>

<script>
  // Plus tard : on modifie le contenu d'une region deja surveillee
  document.getElementById('form-status').textContent =
    'Erreur : e-mail invalide';
</script>

Si vous préférez un aria-live explicite plutôt qu'un rôle, la règle des tests 7.5.1 et 7.5.2 impose d'y adjoindre aria-atomic="true" :

CODE
<!-- aria-live nu : TOUJOURS accompagne de aria-atomic="true" -->
<div id="resultats" aria-live="polite" aria-atomic="true"></div>

Vous voulez un gabarit prêt à coller (HTML, JS et CSS) pour ce pattern de notification ? L'outil gratuit Patterns ARIA, onglet Notifications génère le code d'une région live conforme, conteneur pré-existant compris.

Les quatre pièges qui annulent une région live pourtant présente

Même avec le bon rôle et un conteneur pré-existant, quatre erreurs récurrentes rendent la région muette.

display:none ou aria-hidden au mauvais moment

Une région masquée par aria-hidden="true", par l'attribut hidden, ou par display:none / visibility:hidden au moment de l'insertion du message ne sera pas annoncée. Le motif est valide uniquement si la région est révélée avant l'insertion du contenu. Masquée au repos puis dévoilée puis remplie : d'accord. Remplie alors qu'elle est encore masquée : muette.

Région injectée trop tard dans le DOM

C'est le corollaire du piège du timing : si le conteneur live n'existe qu'au moment où vous voulez annoncer, l'amorçage n'a pas eu lieu. Placez vos conteneurs de statut dans le HTML initial, ou au minimum bien avant la première mise à jour.

Régions imbriquées : la double annonce

Une région live à l'intérieur d'une autre région live provoque souvent une double lecture : le lecteur d'écran annonce la région parente et la région enfant. Évitez d'emboîter role="status", role="alert" ou aria-live les uns dans les autres.

aria-live nu sans aria-atomic="true"

Le test 7.5.1 exige, pour un aria-live explicite, la présence de aria-atomic="true". Sans lui, le lecteur d'écran peut n'annoncer que le fragment modifié plutôt que le message complet, ou ne rien restituer d'intelligible. Rappel : role="status" et role="alert" portent déjà cette valeur de façon implicite, c'est pourquoi les rôles sont plus sûrs qu'un aria-live posé à la main.

Le piège inverse : le sur-annonce (too chatty)

L'excès nuit tout autant que le manque. Mettre role="alert" ou aria-live="assertive" partout, ou brancher une région live sur un conteneur qui se met à jour en continu, transforme l'expérience en spam vocal. La note d'accompagnement de WCAG 4.1.3 est explicite : « There is a risk of making an application too "chatty" for a screen reader user. User testing should be carried out to ensure the appropriate level of feedback is achieved. » Utiliser l'assertif sur du contenu qui n'est ni important ni urgent est d'ailleurs un motif d'échec du critère. La règle : le poli par défaut, l'assertif seulement pour l'urgent. D'autres pièges ARIA fréquents sont recensés dans notre article pièges ARIA courants et impact sur les performances.

7.5 ou 11.x : ne pas confondre avec les erreurs de formulaire

C'est la confusion classique. Les messages d'erreur de saisie de formulaire ne relèvent pas du critère 7.5, mais des critères de la famille 11 (Formulaires) :

  • 11.1 (niveau A) : « Chaque champ de formulaire a-t-il une étiquette ? »
  • 11.10 (niveau A) : « Dans chaque formulaire, le contrôle de saisie est-il utilisé de manière pertinente (hors cas particuliers) ? »
  • 11.11 (niveau A) : « Dans chaque formulaire, le contrôle de saisie est-il accompagné, si nécessaire, de suggestions facilitant la correction des erreurs de saisie ? »

Le critère 7.5 couvre les messages de statut hors formulaire : succès d'une action, mise à jour du panier, chargement, résultats en direct, toasts. La bonne pratique pour associer un message d'erreur à son champ (via aria-describedby, par exemple) est détaillée dans notre guide des formulaires accessibles. Retenez la règle simple : erreur liée à un champ précis → famille 11 ; message d'état général de la page → critère 7.5.

Comment vérifier le critère 7.5 sur vos pages

Le test manuel au lecteur d'écran : le seul verdict fiable

Le 7.5 est fondamentalement un critère à vérification manuelle. Le seul moyen de savoir si un message est réellement annoncé, au bon moment, avec le bon niveau d'urgence, est de le déclencher avec un lecteur d'écran actif (NVDA, VoiceOver, JAWS) et d'écouter. Aucun automate ne peut se substituer à ce test d'écoute.

Ce qu'un outil peut repérer

Un scanner statique peut malgré tout signaler des patterns à risque autour des régions live déjà présentes dans le DOM :

  • une région de statut portant aria-hidden="true" ou l'attribut hidden ;
  • une valeur aria-live non standard (faute de frappe, valeur ≠ polite / assertive / off) ;
  • des régions live imbriquées susceptibles de provoquer une double annonce ;
  • une contradiction aria-live="off" combinée à un rôle qui, lui, annonce (status, alert, log).

Sur notre scanner, ces signaux sont émis sous forme de « à vérifier », jamais comme un verdict de conformité. Le critère 7.5 renvoie systématiquement un statut manuel : l'outil vous montre où regarder, il ne tranche pas à votre place.

Ce qu'un outil ne peut pas voir

Il faut être honnête sur les limites. L'échec le plus fréquent du 7.5 est justement indétectable en statique : un message inséré en JavaScript sans aucun balisage live (<div>Message envoyé</div> sans rôle ni aria-live) ne correspond à aucun sélecteur et passe donc inaperçu du scan. De même, la présence de aria-atomic="true" ou l'usage de role="progressbar" peuvent échapper à l'analyse automatique. Autrement dit : une anomalie détectée n'est pas une non-conformité établie, et un score RGAA Checker n'est pas un taux de conformité RGAA.

C'est cohérent avec le périmètre réel de notre scanner. Sur les 106 critères du RGAA, RGAA Checker en vérifie automatiquement 8, en pré-vérifie 65 (une anomalie est détectée, sa pertinence reste à valider par un humain) et en laisse 33 exclusivement manuels. Le critère 7.5 fait partie de ces 33. Pour repérer les zones à risque sur vos pages avant un audit manuel, vous pouvez lancer une analyse de votre site : les régions live suspectes remonteront en signal « à vérifier », à confirmer ensuite au lecteur d'écran.

Pour aller plus loin sur le réglage fin des régions live (attributs aria-relevant, aria-busy, orchestration dans des interfaces à forte densité de mises à jour), consultez notre article ARIA live régions pour tableaux de bord complexes.

Foire aux questions

Quelle est la différence entre role="status" et role="alert" ? role="status" est poli : il porte les valeurs implicites aria-live="polite" et aria-atomic="true", et n'interrompt pas la synthèse vocale. Il convient à un succès, un résultat ou un état. role="alert" est assertif : implicites aria-live="assertive" et aria-atomic="true", il interrompt la lecture en cours. Réservez-le aux erreurs et aux cas urgents.

Pourquoi ma région aria-live n'annonce-t-elle rien ? La cause la plus fréquente est la règle de pré-existence : la région doit exister (vide) dans le DOM avant l'insertion du message. Un élément créé déjà rempli, masqué par aria-hidden ou display:none au moment de l'insertion, ou porteur d'une valeur aria-live non standard, reste muet.

Les messages d'erreur de formulaire relèvent-ils du critère 7.5 ? Non. Ils relèvent des critères 11.1, 11.10 et 11.11. Le critère 7.5 couvre les messages de statut hors formulaire (succès, panier, chargement, résultats en direct).

Le critère RGAA 7.5 est-il de niveau A ou AA ? Niveau AA. Il correspond au critère de succès WCAG 2.1 · 4.1.3 Status Messages.

À retenir

  • Le critère RGAA 7.5 (niveau AA, correspondance WCAG 4.1.3) demande que les messages de statut soient restitués aux technologies d'assistance sans prendre le focus.
  • Une région n'annonce que si elle existe déjà, vide, dans le DOM avant l'insertion du contenu (règle de pré-existence). Une région créée déjà remplie ne parle pas.
  • role="status" = annonce polie ; role="alert" = annonce assertive qui interrompt ; la progression utilise role="log", role="progressbar" ou role="status" (test 7.5.3).
  • Les erreurs de saisie de formulaire relèvent des critères 11.1, 11.10 et 11.11, pas du 7.5.
  • Sur les 106 critères du RGAA, RGAA Checker en vérifie automatiquement 8, en pré-vérifie 65 et en laisse 33 exclusivement manuels : le 7.5 fait partie de ces 33, l'outil émet donc un signal « à vérifier », jamais un verdict de conformité.

Le meilleur réflexe pour maîtriser le 7.5 reste de l'entendre : activez un lecteur d'écran, déclenchez vos toasts, vos ajouts au panier et vos messages d'erreur, et écoutez ce qui est réellement annoncé. Quelques minutes d'écoute réelle en apprennent souvent plus qu'un long audit statique.

Questions fréquentes

Quelle est la différence entre `role="status"` et `role="alert"` ?

`role="status"` est poli (implicites `aria-live="polite"` et `aria-atomic="true"`), n'interrompt pas la synthèse et convient aux succès, résultats et états ; `role="alert"` est assertif (implicites `aria-live="assertive"` et `aria-atomic="true"`), interrompt la lecture et se réserve aux erreurs et cas urgents.

Pourquoi ma région `aria-live` n'annonce-t-elle rien ?

La cause la plus fréquente est la règle de pré-existence : la région doit exister (vide) dans le DOM avant l'insertion du message ; un élément créé déjà rempli, masqué par `aria-hidden` ou `display:none` au moment de l'insertion, ou porteur d'une valeur `aria-live` non standard reste muet.

Les messages d'erreur de formulaire relèvent-ils du critère 7.5 ?

Non, ils relèvent des critères 11.1, 11.10 et 11.11 ; le 7.5 couvre les messages de statut hors formulaire (succès, panier, chargement, résultats en direct).

Le critère RGAA 7.5 est-il de niveau A ou AA ?

Niveau AA, en correspondance avec le critère de succès WCAG 2.1 · 4.1.3 Status Messages.

Votre site est-il conforme ?

Ne prenez pas de risques avec l'accessibilité. Lancez un audit complet de votre site en quelques minutes et obtenez un rapport détaillé des corrections à apporter.