Description de l'image : Panneau routier comportant une flèche pointant vers la gauche, symbolisant une direction ou un choix.
Messages d'erreur accessibles
Messages d'erreur accessibles : le guide complet
Chaque champ de formulaire que vous créez, chaque validation que vous déclenchez, chaque message d'erreur que vous affichez : ce sont là des moments où les produits numériques peuvent soit inclure, soit exclure des millions de personnes. Voici comment réussir chacun d'entre eux.
Le coût caché des erreurs inutiles
Vous avez sûrement déjà vu ça : un formulaire qui affiche « Entrée non valide » alors que vous venez de saisir soigneusement votre numéro de téléphone. Un processus de paiement qui surligne un champ en rouge sans donner aucune explication. Un message d'erreur qui utilise des codes énigmatiques que seul le développeur qui l'a écrit un vendredi à 23 heures est capable de comprendre.
Il ne s'agit pas là de simples désagréments en matière d'expérience utilisateur. Pour les 1,3 milliard de personnes dans le monde qui vivent avec un handicap, des messages d'erreur mal conçus peuvent rendre un produit numérique totalement inutilisable. Pour les utilisateurs de lecteurs d'écran, un message d'erreur qui ne change que de couleur est invisible. Pour les utilisateurs souffrant de troubles cognitifs, une phrase vague telle que « Une erreur s'est produite » est paralysante. Pour une personne qui dépend de la commande vocale, une erreur de formulaire qui détourne le focus de manière imprévisible perturbe tout le déroulement des tâches.
La création de messages d'erreur accessibles ne se résume pas à ajouter des attributs ARIA après coup. Elle nécessite un langage bien pensé, une structure DOM adaptée, des indications visuelles et non visuelles, ainsi qu'un profond respect pour la diversité de vos utilisateurs. Ce guide passe en revue tous les aspects nécessaires à leur bonne conception, des critères WCAG aux principes de rédaction, en passant par des exemples concrets de code.
Nous nous concentrons sur les erreurs de validation côté client et côté serveur dans les interfaces Web, bien que la plupart des principes s'appliquent également aux applications mobiles natives, aux bornes interactives et aux interfaces vocales. Sauf indication contraire, les références renvoient aux WCAG 2.2 AA.
Ce qu'exige réellement la norme
Les WCAG 2.2, publiées en octobre 2023, constituent la norme actuelle en matière d'accessibilité du Web et servent de référence à la plupart des cadres juridiques, notamment la directive européenne sur l'accessibilité du Web, la loi britannique sur l'égalité et l'ADA américaine. Plusieurs critères de conformité s'appliquent directement aux messages d'erreur. Il est essentiel d'en comprendre la lettre avant de pouvoir aller au-delà.
| Critère | Niveau | Ce qu'il faut | En cas de messages d'erreur |
|---|---|---|---|
| 1.3.1 Informations et relations | A | Exprimez la structure et les relations par le biais de la sémantique, et pas seulement par la présentation. | Un état d'erreur indiqué uniquement par la couleur n'est pas suffisant. Le lien entre un champ et son erreur doit pouvoir être déterminé par programmation — utilisez <label>, aria-invalid="true", et aria-describedby pour associer le texte d'erreur à la saisie. |
| 1.4.1 Utilisation des couleurs | A | N'utilisez pas la couleur comme seul moyen visuel pour transmettre des informations. | Les bordures rouges seules ne suffisent pas. Ajoutez une icône, une étiquette de texte ou un motif. |
| 1.4.3 Contraste (minimum) | AA | Le texte doit présenter un rapport de contraste d'au moins 4,5:1 (3:1 pour les gros caractères). | Un texte d'erreur en rouge clair (#f87171) sur fond blanc n'atteint qu'un rapport d'environ 2,93:1, ce qui est bien inférieur au rapport requis de 4,5:1. Utilisez des teintes plus foncées : la couleur #b91c1c sur fond blanc offre un rapport d'environ 7,1:1 et satisfait largement aux exigences. |
| 2.4.3 Ordre de mise au point | A | L'ordre de priorité doit préserver le sens et la fonctionnalité. | Une gestion inadéquate du focus après un échec de soumission peut rompre la séquence logique (par exemple, si le focus se place après l'erreur, rendant celle-ci inaccessible). Déplacer le focus vers un résumé de l'erreur en cas d'échec de soumission est une technique recommandée — qui répond principalement aux critères SC 3.3.1 et 3.3.2 — et qui permet également de maintenir la cohérence de l'ordre du focus conformément au critère 2.4.3. |
| 3.3.1 Identification des erreurs | A | Si une erreur de saisie est détectée, l'élément concerné est identifié et l'erreur est décrite dans un message. | L'erreur doit être décrite par écrit — et non pas simplement signalée visuellement. |
| 3.3.2 Étiquettes ou instructions | A | Prévoyez des étiquettes ou des instructions lorsque le contenu nécessite une intervention de l'utilisateur. | Les indications de format (par exemple « JJ/MM/AAAA ») doivent être présentes avant l'envoi, et pas seulement en cas d'erreur. |
| 3.3.3 Suggestion d'erreur | AA | Si une erreur est détectée et que des solutions sont connues, veuillez les indiquer. | « Date non valide » n'est pas suffisant. « Entrez une date au format JJ/MM/AAAA, par exemple 23/03/2026 » est correct. |
| 3.3.4 Prévention des erreurs | AA | Pour les soumissions d'ordre juridique, financier ou relatives aux données, procédez à la vérification, à la confirmation ou à l'annulation. | Permettre aux utilisateurs de vérifier et de corriger leur travail avant de le soumettre définitivement. |
| 4.1.3 Messages d'état | AA | Les messages d'état peuvent être déterminés par programmation via un rôle ou une propriété sans que l'élément ne reçoive le focus. | Utilisation role="alert", role="status", ou aria-live afin que les utilisateurs d'AT reçoivent le message. |
De nombreuses équipes interprètent l'expression « identifiés et décrits dans le texte » comme signifiant simplement ajouter une étiquette. Or, le champ concerné par l'erreur doit être identifiable, c'est-à-dire que le message d'erreur doit soit figurer à côté du champ, soit que le nom du champ doit apparaître dans le texte de l'erreur. La mention « Veuillez corriger les champs surlignés » n'est pas conforme.
Qu'est-ce qui caractérise un bon message d'erreur ?
Un message d'erreur bien conçu comporte quatre éléments indispensables. Chacun d'entre eux remplit une fonction bien précise : si vous en supprimez un seul, vous détériorez l'expérience d'une partie de vos utilisateurs.
Le cadre linguistique : six règles pour la rédaction de textes d'erreurs
Les messages d'erreur relèvent de la rédaction UX. Ce ne sont pas des sorties de journal. Ce ne sont pas des notes destinées aux développeurs. Il s'agit d'une communication humaine en situation de stress, rédigée à l'intention d'une personne qui vient d'échouer et qui a besoin de réussir.
1. Soyez précis
Expliquez clairement à l'utilisateur ce qui ne va pas. « Invalide » ne lui apprend rien. « Le mot de passe doit comporter au moins 8 caractères » lui dit tout.
2. Être concret
Le message doit indiquer, de manière implicite ou explicite, comment corriger l'erreur. Veuillez inclure des exemples de mise en forme lorsque celle-ci n'est pas évidente.
3. Évitez de rejeter la faute sur les autres
Ne dites jamais « vous avez saisi », « votre saisie » ou « vous avez échoué ». Préférez les constructions passives : « L'adresse e-mail saisie est incomplète. »
4. Utilisez un langage simple
Adoptez un style adapté à des lecteurs d'environ 11 ans. Évitez le jargon, les expressions techniques et les formules passives-agressives telles que « veuillez réessayer ».
5. Choisissez le bon moment
Afficher les erreurs en ligne lorsque l'utilisateur quitte le champ, et non à chaque frappe. N'afficher le récapitulatif des erreurs qu'après une tentative de soumission.
6. Tenez compte du contexte
Une erreur dans un formulaire de paiement mérite davantage d'attention qu'un simple filtre de recherche. Adaptez le ton et le niveau de détail à l'importance de la tâche.
Messages d'erreur réels : avant et après
La différence entre un message d'erreur incompréhensible et un message d'erreur compréhensible se résume souvent à quelques mots et à deux attributs. Ces comparaisons montrent précisément ce qui change — et pourquoi chaque modification est importante.
Validation des champs obligatoires
Problèmes : N'identifie pas qui champ. Ne déclenche aucune action. Souvent mis en évidence uniquement par un changement de couleur (non conforme à la section 1.4.1). Non role="alert" ce qui signifie que les lecteurs d'écran ne le liront pas à voix haute.
Pourquoi ça marche : Donne un nom au champ. Explique pourquoi il est nécessaire. Est associé au champ de saisie via aria-describedby. Contraste du texte ≥ 4,5:1. Les lecteurs d'écran l'annoncent lors de la validation via role="alert".
Validation du format (date)
Problèmes : l'utilisateur ne sait pas quel format est attendu. Le système lui indique ce qui ne va pas, mais ne lui explique pas comment y remédier. Non conforme à la section 3.3.3 (Suggestion d'erreur). Aucun exemple fourni.
Pourquoi cela fonctionne : précise le format requis. Donne un exemple concret (conforme à la section 3.3.3). Concis et clair. Sera lu par les lecteurs d'écran dès que le focus quitte le champ.
Validation du mot de passe
Problèmes : le terme « faible » est subjectif et n'indique pas de solution précise. Il est généralement représenté par une barre de niveau rouge, ce qui constitue un retour d'information purement visuel (non conforme à la section 1.4.1). Il n'y a aucun lien entre l'état de la barre et la sortie de l'interface utilisateur.
Pourquoi cela fonctionne : chaque critère est énuméré. Les utilisateurs peuvent passer en revue chaque lacune et y remédier. L'indicateur de niveau complète ce texte et utilise à la fois une couleur ET une mention écrite (« Faible / Fort »). Aucune information n'est transmise par la couleur seule.
Erreur de serveur / système
Problèmes : le code technique n'a aucun sens pour la plupart des utilisateurs. Le message « Une erreur s'est produite » n'indique aucune marche à suivre. Injection dans le DOM sans zone interactive — invisible pour les lecteurs d'écran. Aucune suggestion de solution.
Pourquoi ça marche : Langage clair. Indique ce qui n'a pas fonctionné. Propose deux solutions de secours claires. Intégré dans un aria-live="assertive" région afin que les lecteurs d'écran la lisent immédiatement. Le curseur se trouve désormais sur le message.
Le meilleur message d'erreur est celui qui empêche l'erreur de se produire. Le deuxième meilleur message d'erreur est celui qui rend la solution évidente.
Types d'erreurs et quand les utiliser
Différents scénarios d'erreur nécessitent différents modèles d'interaction. Le choix d'un conteneur ou d'un mécanisme d'affichage inadapté constitue l'une des défaillances d'accessibilité les plus courantes dans les formulaires.
| Motif | Idéal pour | Mise en œuvre d'ARIA | Comportement de mise au point | Obligatoire |
|---|---|---|---|---|
| Erreur de champ en ligne | Validation immédiate au niveau du champ (lors du changement de mise au point) | aria-invalid="true" + aria-describedby |
Pas de changement de mise au point. Une erreur se produit lors de la mise au point suivante. | Obligatoire |
| Bannière récapitulative des erreurs | Erreurs lors de l'envoi d'un formulaire comportant plusieurs champs | role="alert" ou aria-live="assertive" |
Lors de la soumission, placez le curseur sur l'en-tête du résumé. | Obligatoire pour les formulaires comportant plus de 3 champs |
| Notification par bandeau / barre de notification | Erreurs non liées au formulaire (échec de l'enregistrement, problème de réseau) | role="alert" ou aria-live="assertive" |
Ne PAS déplacer le focus. Fermer automatiquement après ≥ 5 secondes (ou jamais). | Recommandé |
| Fenêtre de dialogue modale d'erreur | Confirmation d'une action destructive, erreurs critiques | role="dialog" + aria-modal="true" + aria-labelledby |
Déplacer le curseur sur le premier élément interactif à l'intérieur de la boîte de dialogue. | En cas d'erreurs critiques ou irréversibles |
| Zone d'alerte au niveau de la page | Erreurs de serveur signalées après le rafraîchissement de la page | role="alert" at top of <main> |
Ce doit être le premier élément pouvant recevoir le focus après le lien de saut. | Obligatoire s'il est présent au chargement |
| Message de courtoisie | Commentaires à faible priorité (enregistrés automatiquement, champ facultatif ignoré) | aria-live="polite" + role="status" |
Pas de changement de sujet. Annoncé à la fin du discours en cours. | Facultatif / dépend du contexte |
L'approche à deux niveaux pour les formulaires à champs multiples
Pour les formulaires comportant au moins trois champs, un seul modèle ne suffit pas. Le Government Digital Service (GDS) et le guide des pratiques de rédaction ARIA recommandent tous deux un système à deux niveaux : un résumé des erreurs en haut du formulaire, ainsi que des messages d'erreur intégrés à côté de chaque champ concerné.
En cas de soumission comportant des erreurs : (1) Insérer un bloc récapitulatif des erreurs en haut du formulaire, avec un titre du type « Il y a 3 erreurs. Corrigez-les pour continuer. » et des liens vers chaque champ erroné. (2) Déplacer le focus du clavier sur ce titre récapitulatif. (3) Chaque lien du récapitulatif permet d'accéder directement au champ correspondant. (4) Chaque champ affiche son propre message d'erreur intégré, accessible via aria-describedby. Les utilisateurs de lecteurs d'écran entendent les deux niveaux ; les utilisateurs voyants voient les deux niveaux. Personne n'est laissé de côté.
Modèles de code qui fonctionnent
Comprendre la théorie, c'est déjà la moitié du chemin. Vous trouverez ci-dessous des modèles prêts à l'emploi pour les scénarios les plus courants, accompagnés d'une liste des critères WCAG auxquels chaque attribut répond.
Validation des champs en ligne
<!-- The label is always present and always linked --> <div class="field-group"> <label for="email"> Email address <span class="required-indicator" aria-label="required"> *</span> </label> <input type="email" id="email" name="email" autocomplete="email" aria-required="true" aria-invalid="true" <!-- set when invalid --> aria-describedby="email-hint email-error" /> <!-- Hint text always shown (WCAG 3.3.2) --> <p id="email-hint" class="field-hint"> We'll send your confirmation here. </p> <!-- Error message (shown only on error) --> <p id="email-error" class="field-error" role="alert" aria-live="assertive" > <!-- inject error text here --> Enter a complete email address — for example, [email protected] </p> </div>
Résumé des erreurs (formulaires à champs multiples)
<!-- Inject this above the form on submission, then focus #error-summary --> <div id="error-summary" role="alert" aria-labelledby="error-summary-title" tabindex="-1" <!-- allows programmatic focus --> class="error-summary" > <h2 id="error-summary-title"> There are 2 errors. Fix these to continue. </h2> <ul> <li><a href="#email">Email address: enter a complete email</a></li> <li><a href="#dob">Date of birth: use DD/MM/YYYY format</a></li> </ul> </div> <!-- JavaScript: move focus to summary after injection --> <script> const summary = document.getElementById('error-summary'); summary.focus(); // fires after DOM update </script>
Erreurs dynamiques / AJAX (sans actualisation de la page)
Lorsque des erreurs sont renvoyées de manière asynchrone — par exemple, à la suite d'un appel d'API —, on ne peut pas compter sur le chargement de la page pour les signaler. Le modèle de zone active ARIA est ici indispensable.
// Set up the live region once on page load (empty, hidden) // <div id="live-error" role="alert" aria-live="assertive" aria-atomic="true"></div> async function submitForm(data) { try { const res = await fetch('/api/save', { method: 'POST', body: data }); if (!res.ok) throw new Error(await res.text()); announceStatus('Your changes have been saved.', 'polite'); } catch (err) { announceStatus( 'We couldn\'t save your changes. Try again or contact support.', 'assertive' ); } } function announceStatus(message, urgency = 'polite') { const region = document.getElementById('live-error'); region.setAttribute('aria-live', urgency); // Clear first to re-trigger announcement if same message region.textContent = ''; requestAnimationFrame(() => { region.textContent = message; }); }
Les lecteurs d'écran ne lisent à voix haute que le contenu qui changements dans une région active. Si vous insérez deux fois de suite le même message d'erreur, certains AT ne le réafficheront pas. Solution : effacez la région pour la vider, puis remplissez-la dans un requestAnimationFrame rappel. Cela force la modification du DOM que l'AT attend.
Liste de contrôle pour l'audit de l'accessibilité
Utilisez cette liste de contrôle lors des revues de conception, des revues de code et des contrôles qualité. Elle couvre tous les critères de niveau A et AA des WCAG 2.2 relatifs aux états d'erreur.
Visuel et contenu
- Les erreurs sont signalées par du texte, et non uniquement par la couleur (WCAG 1.4.1)
- Le texte de l'erreur présente un rapport de contraste d'au moins 4,5:1 par rapport à son arrière-plan (WCAG 1.4.3)
- Une icône ou un repère visuel vient compléter le changement de couleur
- Le message d'erreur mentionne le champ ou se trouve juste à côté de celui-ci
- Le message d'erreur explique ce qui ne va pas (et ne se contente pas d'indiquer « invalide »)
- Le message d'erreur indique comment résoudre le problème (WCAG 3.3.3)
- Des exemples de format sont fournis pour les champs de date, de numéro de téléphone, de code postal et autres champs similaires
- Le langage utilisé est simple, non technique et n'attribue aucune responsabilité
- Le message d'erreur ne disparaît pas tant que l'erreur n'est pas résolue
- Les indications de format (par exemple « JJ/MM/AAAA ») s'affichent avant l'envoi, et pas seulement en cas d'erreur
Programmation et technologies d'assistance
aria-invalid="true"est défini sur la valeur erronée- L'élément du message d'erreur est lié via
aria-describedbyà l'entrée - Utilisations du conteneur d'erreurs
role="alert"ouaria-live="assertive" - La zone réservée aux erreurs n'est pas vide dans le DOM avant que des erreurs n'apparaissent (conteneur vide prérempli)
- Le résumé des erreurs est généré et mis en évidence par programmation en cas d'échec de l'envoi du formulaire
- Les liens du récapitulatif des erreurs renvoient vers le champ correspondant du formulaire
- Les tests avec les lecteurs d'écran ont été réussis sur NVDA/Firefox et VoiceOver/Safari
- Le titre de la page est mis à jour pour indiquer l'état d'erreur lors de l'envoi d'un formulaire en pleine page
- Utilisation des messages d'état
role="status"avecaria-live="polite"pour des commentaires non critiques
Mise au point et clavier
- Le curseur se place sur le résumé des erreurs (ou sur le champ de la première erreur) après un échec de l'envoi
- L'indicateur de sélection est clairement visible sur tous les éléments interactifs en état d'erreur (WCAG 2.4.11)
- Les boîtes de dialogue d'erreur modales retiennent le focus à l'intérieur de la boîte de dialogue
- Le fait d'ignorer une erreur (par exemple, en fermant une fenêtre contextuelle) ramène le focus à une position logique
- Aucune interaction ne nécessite l'utilisation d'un dispositif de pointage
- Les erreurs de délai d'expiration fournissent un avertissement suffisant et laissent le temps de prolonger la session (WCAG 2.2.1)
La directive WCAG 3.3.6 (Prévention des erreurs — Tous) vous invite à permettre aux utilisateurs de vérifier, de confirmer et d'annuler toutes les soumissions, et pas seulement celles de nature financière. Bien qu'il s'agisse d'un critère de niveau AAA qui n'est pas légalement obligatoire dans la plupart des contextes, cela réduit considérablement le stress lié aux erreurs chez les utilisateurs présentant des troubles cognitifs. Considérez-le comme la norme de référence à respecter.
Comment nous en sommes arrivés là : un bref historique
role="alert" et aria-live modèles. Une prise en charge cohérente par les navigateurs et les technologies d'assistance est enfin possible pour les notifications d'erreurs dynamiques.
Les messages d'erreur, reflet des valeurs de votre produit
Le message d'erreur est l'un des moments les plus révélateurs de toute expérience numérique. Il apparaît précisément au moment où l'utilisateur est sous pression : lorsqu'il a commis une erreur ou qu'un imprévu indépendant de sa volonté s'est produit. La manière dont vous réagissez à ce moment-là en dit long sur l'importance que vous accordez à l'inclusion.
Une bordure rouge sans texte n'est pas un message d'erreur. Une liste de codes n'est pas un message d'erreur. Une vague mention du type « une erreur s'est produite » n'est pas un message d'erreur. Un message d'erreur accessible est un message clair, bienveillant et concret, rédigé dans un langage compréhensible par tous — y compris les 26 % d'utilisateurs en situation de handicap, les 15 % qui utilisent la navigation au clavier et les 100 % d'utilisateurs qui rencontreront une erreur à un moment ou à un autre.
L'accessibilité n'est pas une fonctionnalité. C'est un critère de qualité qui s'applique à chaque fonctionnalité que vous proposez — et c'est dans les messages d'erreur que cette qualité est mise à l'épreuve dans les conditions les plus difficiles.
La bonne nouvelle, c'est que la mise en place de messages d'erreur accessibles ne demande que très peu d'efforts supplémentaires lorsqu'elle est intégrée dès le début. Les attributs ARIA sont succincts. Les consignes rédactionnelles sont claires. Les modèles sont bien établis. Ce qu'il faut, c'est de la volonté : une décision délibérée de tester avec des technologies d'assistance, d'écrire pour des humains plutôt que pour des systèmes, et de considérer chaque situation d'échec comme une occasion de gagner la confiance des utilisateurs.
Chez AIOPSGROUP, une société du groupe valantic, nous développons des produits numériques accessibles à tous. L'ingénierie de l'accessibilité est intégrée à notre système de conception, à nos revues de code et à notre processus d'assurance qualité — elle n'est pas simplement ajoutée en fin de processus. Si votre équipe a besoin d'aide pour auditer, mettre en œuvre ou créer de A à Z un système de conception accessible, nous serons ravis de vous aider.
Guide de référence rapide WCAG 2.2 — Aide à la saisie · Guide des bonnes pratiques de création ARIA · Composant de messages d'erreur GDS · Rapport « Million » 2024 de WebAIM