Formulaires : Lier les erreurs aux champs (aria-describedby)
L'erreur classique
L'utilisateur remplit un champ, clique sur "Envoyer", et le message d'erreur apparaît visuellement. Mais pour un utilisateur de lecteur d'écran, si le focus n'est pas géré ou si le lien sémantique manque, l'erreur est invisible.
La structure robuste
Pour une accessibilité totale (surtout en SPA/React), nous avons besoin de 3 choses :
- Indiquer que le champ est en erreur (
aria-invalid). - Lier le message au champ (
aria-describedby). - Avertir de l'apparition du message (
role="alert").
<div class="form-group">
<label for="email">Votre Email</label>
<input
type="email"
id="email"
name="email"
aria-invalid="true"
aria-describedby="email-error"
/>
<!--
role="alert" permet au lecteur d'écran d'annoncer
le message dès qu'il apparaît dans le DOM via JS
-->
<span id="email-error" class="error-message" role="alert">
Veuillez entrer une adresse email valide.
</span>
</div>
Pourquoi ce trio ?
Chaque attribut joue un rôle précis dans la chronologie de l'interaction :
-
L'état (
aria-invalid="true") : C'est le drapeau. Il modifie la sémantique du champ. Lorsqu'un utilisateur de lecteur d'écran arrive sur l'input, il entendra "Invalide" ou "Erreur" juste après le label. Sans ça, il ne sait pas que le champ pose problème. -
L'association (
aria-describedby="ID") : C'est le contexte. Cela lie sémantiquement le message au champ. Si l'utilisateur navigue au clavier et revient sur le champ pour le corriger, le lecteur d'écran lira le label puis le contenu du message d'erreur associé. -
L'alerte (
role="alert") : C'est l'immédiateté. C'est le point crucial pour les applications modernes (SPA/React). Si l'erreur apparaît dynamiquement (aublurou au clic sans rechargement de page), lerole="alert"transforme la balise en une zone de notification (Live Region). Le lecteur d'écran interrompra ou attendra la fin de sa phrase pour vocaliser le message d'erreur dès son apparition, même si le focus de l'utilisateur est encore dans le champ.
Astuce d'expert : Si vous avez un long formulaire avec de multiples erreurs lors de la soumission, évitez de mettre
role="alert"sur tous les messages individuels pour ne pas créer une cacophonie. Préférez déplacer le focus JavaScript vers un résumé des erreurs en haut de page (Summary), ou directement vers le premier champ invalide. Dans ce cas,aria-describedbysuffira à lire l'erreur une fois le focus arrivé sur le champ.