Aller au contenu principal
Technique13 mars 20267 min

ARIA alert : notifier les utilisateurs de lecteurs d'écran

En Bref : L'essentiel à retenir

  • Le rôle alert crée une live région assertive qui interrompt la lecture du lecteur d'écran pour annoncer immédiatement le message.
  • N'utilisez alert que pour les messages urgents nécessitant une attention immédiate comme les erreurs de formulaire ou les alertes de sécurité.
  • Pour les messages moins urgents, préférez aria-live="polite" qui attend une pause dans la lecture avant d'annoncer le contenu.
  • L'élément avec rôle="alert" doit être présent dans le DOM avant l'insertion du message pour une annonce fiable dans tous les lecteurs d'écran.
ARIALive régionsNotificationsJavaScriptAccessibilité

Quand le contenu d'une page change dynamiquement sans rechargement, les utilisateurs de lecteurs d'écran peuvent manquer l'information. Le rôle ARIA alert permet de signaler les messages importants. Mais attention : mal utilisé, il peut rendre l'expérience insupportable.

Comment fonctionne role="alert"

Le rôle alert crée une live région assertive. Quand son contenu change, le lecteur d'écran :

  1. Interrompt la lecture en cours
  2. Annonce immédiatement le nouveau contenu
  3. Reprend la lecture précédente

C'est l'équivalent ARIA de aria-live="assertive" avec aria-atomic="true".

CODE
<div role="alert">
  Votre session expire dans 2 minutes.
</div>

[!WARNING] Une alerte interrompt l'utilisateur. Pour les messages non urgents, utilisez aria-live="polite" qui attend une pause naturelle.

Cas d'usage appropriés

SituationUtiliser alert ?
Erreur de validation formulaireOui
Session sur le point d'expirerOui
Problème de connexion réseauOui
Confirmation d'ajout au panierNon (polite)
Nombre de résultats mis à jourNon (polite)
Message de bienvenueNon

Implémentation correcte

Pattern 1 : conteneur prêt dans le DOM

Pour une annonce fiable, le conteneur doit exister avant l'insertion du message :

CODE
<!-- Conteneur vide présent au chargement -->
<div role="alert" id="form-errors" aria-live="assertive"></div>

<form id="contact-form">
  <!-- Champs du formulaire -->
</form>
CODE
function showError(message) {
  const errorContainer = document.getElementById('form-errors');
  errorContainer.textContent = message;
}

// Utilisation
showError('Le champ email est requis.');

Pattern 2 : injection dynamique

Si vous devez créer l'élément dynamiquement, ajoutez un léger délai :

CODE
function showAlert(message) {
  // Créer le conteneur
  const alert = document.createElement('div');
  alert.setAttribute('role', 'alert');

  // Ajouter au DOM d'abord
  document.body.appendChild(alert);

  // Puis insérer le message (après un cycle de rendu)
  requestAnimationFrame(() => {
    alert.textContent = message;
  });

  // Supprimer après un délai
  setTimeout(() => alert.remove(), 10000);
}

[!TIP] Le pattern 1 (conteneur préexistant) est plus fiable. Certains lecteurs d'écran ne détectent pas les éléments ajoutés dynamiquement.

Erreurs de formulaire accessibles

Voici un pattern complet pour les erreurs de validation :

CODE
<form id="login-form" novalidate>
  <div role="alert" id="form-alert" aria-live="assertive"></div>

  <div class="field">
    <label for="email">Email</label>
    <input
      type="email"
      id="email"
      name="email"
      aria-describedby="email-error"
      required>
    <span id="email-error" class="error" hidden></span>
  </div>

  <button type="submit">Connexion</button>
</form>
CODE
document.getElementById('login-form').addEventListener('submit', (e) => {
  e.preventDefault();
  const errors = validateForm();

  if (errors.length > 0) {
    // Message global dans l'alerte
    document.getElementById('form-alert').textContent =
      `${errors.length} erreur(s) dans le formulaire.`;

    // Messages individuels près des champs
    errors.forEach(error => {
      const errorSpan = document.getElementById(`${error.field}-error`);
      errorSpan.textContent = error.message;
      errorSpan.hidden = false;
    });

    // Focus sur le premier champ en erreur
    document.getElementById(errors[0].field).focus();
  }
});

aria-live="polite" : l'alternative non intrusive

Pour les mises à jour informatives mais non urgentes :

CODE
<div aria-live="polite" id="search-status">
  <!-- Mis à jour dynamiquement -->
</div>
CODE
// L'annonce attend que l'utilisateur fasse une pause
document.getElementById('search-status').textContent =
  '42 résultats trouvés pour "accessibilité"';

Comparaison

AttributComportementCas d'usage
role="alert"Interrompt immédiatementErreurs, alertes de sécurité
aria-live="assertive"Interrompt immédiatementÉquivalent à alert
aria-live="polite"Attend une pauseConfirmations, mises à jour info
aria-live="off"Pas d'annonceDésactiver temporairement

Le rôle status : informations non urgentes

Pour des messages informatifs comme "Sauvegarde en cours" :

CODE
<div role="status" aria-live="polite">
  Vos modifications ont été enregistrées.
</div>

role="status" est équivalent à aria-live="polite" avec aria-atomic="true".

aria-atomic : tout ou partie ?

Par défaut, role="alert" a aria-atomic="true" : le contenu entier est annoncé.

Si vous mettez à jour seulement une partie et voulez annoncer uniquement le changement :

CODE
<div aria-live="polite" aria-atomic="false">
  <span>Température actuelle : </span>
  <span id="temp-value">22°C</span>
</div>

Avec aria-atomic="false", seul "23°C" serait annoncé lors de la mise à jour.

Erreurs courantes

1. Trop d'alertes

CODE
// Mauvais : chaque frappe déclenche une alerte
input.addEventListener('keyup', () => {
  showAlert(`${input.value.length} caractères`);
});

// Bon : debounce et aria-live polite
let timeout;
input.addEventListener('keyup', () => {
  clearTimeout(timeout);
  timeout = setTimeout(() => {
    statusDiv.textContent = `${input.value.length} caractères`;
  }, 500);
});

2. Alert pour du contenu non urgent

CODE
<!-- Trop intrusif pour une simple confirmation -->
<div role="alert">Produit ajouté au panier</div>

<!-- Approprié -->
<div role="status" aria-live="polite">Produit ajouté au panier</div>

3. Doubler avec aria-live="assertive"

CODE
<!-- Redondant : alert implique déjà assertive -->
<div role="alert" aria-live="assertive">Message</div>

<!-- Suffisant -->
<div role="alert">Message</div>

4. Contenu présent au chargement

CODE
<!-- Sera annoncé au chargement de la page ! -->
<div role="alert">
  Bienvenue sur notre site.
</div>

<!-- Utiliser role="alert" uniquement pour du contenu dynamique -->

Alertes fermables

Si l'utilisateur peut fermer l'alerte, assurez-vous que l'action est accessible :

CODE
<div role="alert" id="session-warning">
  <p>Votre session expire dans 2 minutes.</p>
  <button onclick="dismissAlert()">
    Prolonger la session
  </button>
</div>
CODE
function dismissAlert() {
  const alert = document.getElementById('session-warning');
  alert.hidden = true;
  // Retourner le focus là où il était, ou sur un élément logique
}

Test avec lecteurs d'écran

Pour vérifier vos alertes :

  1. NVDA (Windows) : l'alerte est annoncée immédiatement
  2. VoiceOver (macOS) : "Alert: [message]"
  3. JAWS : "Alert, [message]"

Si l'alerte n'est pas annoncée, vérifiez que le conteneur existe dans le DOM avant l'insertion du contenu.

Critères RGAA concernés

CritèreExigence
7.1Scripts accessibles aux technologies d'assistance
11.10Messages d'erreur pertinents
11.11Contrôle de saisie accessible

Conclusion

role="alert" est un outil puissant mais à utiliser avec parcimonie. Réservez-le aux messages véritablement urgents qui nécessitent une attention immédiate. Pour tout le reste, aria-live="polite" offre une expérience moins intrusive et plus agréable pour les utilisateurs de lecteurs d'écran.

Analysez l'accessibilité de vos notifications avec RGAA Checker : notre outil vérifie la présence et la cohérence des live régions sur vos pages.

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.