Validation de formulaire
Accès rapide à l’exemple
Fiche explicative
Rappel sur la portée de cette fiche : Les notions d’accessibilité abordées se concentrent sur des critères fonctionnels, ainsi que sur leur mise en œuvre technique. Pour une couverture complète des requis d’accessibilité, il importe de se référer aux Règles d’accessibilité des contenus Web. Voir à ce sujet la section Les règles de la formation du Laboratoire.
Le composant validation de formulaire met en application divers critères d’accessibilité des formulaires, avec une attention particulière portée à la validation des données saisies. Cette dernière consiste à :
- vérifier si les données inscrites correspondent aux formats ou aux paramètres attendus;
- aviser l’internaute d’éventuelles erreurs, afin qu’elles puissent être corrigées avant l’envoi final.
Deux approches de validation sont employées dans l’exemple : champ par champ, lorsque le focus quitte le champ, et de façon globale, quand on soumet le formulaire. Idéalement, il est souhaitable de combiner ces deux méthodes afin de renforcer la prévention des erreurs.
Pour différentes raisons, les personnes ayant des limitations peuvent avoir plus de difficultés à faire des saisies sans erreur, à détecter qu’elles ont fait une erreur, ou à percevoir une vue d’ensemble des champs à corriger. Une validation de formulaire accessible et conviviale évite à ces clientèles de recommencer des opérations qui leur demandent généralement plus de temps et d’efforts que pour des personnes sans limitations.
Voici les principaux comportements attendus avec les outils d’adaptation (lecteurs d’écran, commandes vocales, etc.) et la navigation au clavier. Ces critères sont répartis selon les méthodes de validation du formulaire.
A) Pour la validation globale (à la soumission du formulaire)
- (Recommandé) La validation utilise l’approche de la liste d’erreurs :
- Les erreurs sont présentées en début de formulaire sous forme de liste et expliquées en texte.
- Le focus est déplacé sur cette liste d’erreurs.
- La liste d’erreurs contient un lien vers chaque champ à corriger. Le libellé de ces liens évoque clairement le champ de destination.
- Pour chaque champ en erreur, une explication de l’erreur est fournie en texte et lui est associée par voie de programmation, de sorte que les lecteurs d’écran lisent ce texte au focus du champ.
- (Recommandé) La description de l’erreur est communiquée à même l’étiquette du champ, plutôt que par d’autres procédés d’association. Pour plus de détails, voir la section Explications techniques.
Remarques complémentaires
L’approche de la liste d’erreurs sur laquelle on redirige le focus n’est pas une exigence de conformité aux WCAG. Cependant, il s’agit d’une technique conseillée (advisory technique) par la documentation associée pour répondre à certains critères du standard. Nous recommandons vivement son intégration, étant donné ses nombreux avantages :
- Elle permet aux personnes qui n’ont pas de vue d’ensemble du formulaire d’avoir une perception globale des erreurs et de ne pas avoir à les chercher.
- Elle facilite l’accès aux personnes naviguant par d’autres moyens que la souris.
- Elle attire l’attention des personnes ayant des limitations cognitives.
Certains formulaires déplacent le focus seulement sur le premier champ à corriger. Cela peut être acceptable s’il n’y a qu’une erreur, mais insuffisant quand il y en a plusieurs. Pour des interactions cohérentes et prévisibles, il vaut donc mieux toujours utiliser le principe de la liste d’erreurs.
B) Pour la validation en sortie du champ
- À la sortie du champ en erreur, un message d’état est transmis aux lecteurs d’écran pour annoncer la description de l’erreur et le champ concerné. Cela est nécessaire, car le champ n’est plus en focus.
- Le texte explicatif de l’erreur est également associé par voie de programmation au champ concerné, de sorte que les lecteurs d’écran lisent ce texte quand le champ est de nouveau mis en focus par l’utilisateur.
Voici d’autres points à surveiller sur le plan fonctionnel, pour un formulaire. Cette liste n’est pas exhaustive.
- Chaque champ de formulaire est associé à une étiquette par voie de programmation, de sorte que le libellé de l’étiquette est annoncé par les lecteurs d’écran au focus du champ.
- Les champs de formulaire peuvent être sélectionnés avec des outils de commandes vocales, en dictant les mots de leur étiquette visible à l’écran.
- Tous les contrôles de formulaire peuvent être parcourus et activés au clavier.
- Toute instruction de saisie, tel le format attendu, est associée à son champ par voie de programmation, de sorte à être annoncée par les lecteurs d’écran au focus du champ.
- (Recommandé) Indiquer le format attendu à même l’étiquette du champ, plutôt que d’utiliser d’autres procédés d’association. Pour plus de détails, voir la section Explications techniques.
- Les champs obligatoires sont reconnus et annoncés comme tels par les outils d’adaptation. Cette information doit être perceptible pour tous les utilisateurs, avant même la validation du formulaire.
- (Bonne pratique) Si un symbole (ex. : astérisque) signale la présence de champs obligatoires, la signification de ce symbole est expliquée en début de formulaire.
- Lorsqu’un texte indicatif (placeholder) est placé dans un champ d’édition, il n’est pas utilisé en remplacement des étiquettes de champs. En effet, ce détournement de la fonction des placeholders peut créer des enjeux avec certains outils d’adaptation. Pour en savoir plus sur ces obstacles, ainsi que sur d’autres types d’impacts pour diverses clientèles, lire la rubrique 1.3 Adaptable – Les formulaires des notes de la formation.
- (Bonne pratique) Pour les utilisateurs qui disposent d’une zone de visualisation réduite (ex. : avec un grossissement d’écran), il est souhaitable de placer les champs d’édition ou les zones de liste déroulante sous leur étiquette. Pour les boutons radio et cases à cocher, le champ est placé à gauche de l’étiquette; les options du même groupe de champs sont disposées verticalement.
Rôles, états et propriétés ARIA
- Les champs obligatoires ont un attribut
aria-required
défini àtrue
. - (Optionnel) Les champs en erreur peuvent recevoir un attribut
aria-invalid
défini àtrue
. Cette valeur bascule àfalse
lorsque la validation détermine que le champ répond aux critères de saisie.- Remarque : De manière générale, il n’est pas nécessaire d’employer cet attribut s’il existe une association programmatique correcte entre le message d’erreur et son champ concerné.
- Les instructions de saisie (ex. : format attendu), les messages d’erreurs et les suggestions de correction sont associées par voie de programmation à leur champ correspondant. Pour ce faire, chaque fois que possible, il est recommandé d’intégrer ces informations à même l’étiquette du champ (
<label>
). Ou, dans le cas d’un groupe de cases à cocher ou de boutons radio, directement dans la légende du groupe de champs (<legend>
). En effet, cette approche comporte certains avantages comparativement à d’autres techniques d’association programmatique comme l’emploi des attributsaria-labelledby
ouaria-describedby
:- Le positionnement dans l’étiquette assure un ordre naturel de lecture, tant visuellement qu’avec les outils d’adaptation. Pour des personnes disposant d’une zone de visualisation réduite, des instructions et messages placés sous les champs peuvent être perçus à retardement, après une tentative de saisie.
- Pour les groupes de champs, le positionnement dans la légende aide à comprendre que les informations s’appliquent à l’ensemble du groupe, et non à un bouton radio ou une case à cocher spécifique.
- Le contenu des étiquettes de champ et des légendes de groupe est consultable depuis l’option des lecteurs d’écran qui liste l’ensemble des champs de formulaire. En revanche, les informations transmises depuis
aria-describedby
ne sont pas reprises par tous les lecteurs d’écran depuis cette fonctionnalité. - À ce jour, JAWS (version 2025 et antérieures) n’annonce pas les informations associées à une légende de groupe de champs depuis
aria-describedby
.
- Lors de la validation en sortie du champ, le texte correspondant au message d’erreur est repris dans une zone d’alerte, visuellement cachée par un positionnement hors écran. Cette zone est un
<div>
auquel on assignerole="alert"
. Ce rôle permet de communiquer le message le plus rapidement possible aux lecteurs d’écran, lorsque le focus quitte le champ en erreur.- Remarque : Il est aussi possible d’utiliser l’attribut
aria-live
avec une valeurassertive
, en remplacement du rôle d’alerte. Cependant, le rôle d’alerte est mieux reconnu par certaines combinaisons de lecteurs d’écran et de navigateurs. Voir à ce sujet Enjeux connus avec les outils d’adaptation.
- Remarque : Il est aussi possible d’utiliser l’attribut
Autres considérations techniques
- Divers aspects de la validation de formulaire sont gérés par JavaScript, notamment :
- La validation des formats attendus et la détection des erreurs.
- L’insertion des explications des erreurs dans les étiquettes de champs ou les légendes de groupes de champs concernés.
- Lors d’une validation de champ en sortie, l’injection du message d’erreur dans la zone d’alerte visuellement cachée (hors écran).
- La production de la liste d’erreurs.
- La mise en focus de la liste d’erreurs, lors d’une validation globale, et la mise à jour dynamique de cette liste, dans le cas d’une validation en sortie d’un champ.
- Afin de permettre une redirection du focus sur la liste d’erreurs (à la soumission globale), un
tabindex="-1"
est donné à l’élément qui reçoit ce focus. Dans l’exemple, il s’agit du conteneur de la liste. - Tous les champs utilisés dans le formulaire d’exemple sont des éléments de formulaire HTML natifs (approche recommandée). Cependant, si on conçoit des champs personnalisés (non natifs), toutes les interactions clavier prévues doivent être recodées avec JavaScript.
Éviter des validations de champ au moment de la saisie
Si l’on utilise une approche de validation avant la soumission globale du formulaire, il convient de privilégier des rétroactions en sortie du champ, plutôt que durant la saisie. En effet, l’apparition de messages d’erreurs pendant le remplissage d’un champ peut créer des enjeux d’utilisabilité et d’accessibilité :
- Pour plusieurs clientèles, notamment celles qui ont des limitations cognitives : cela peut perturber la concentration ou générer du stress.
- Avec un lecteur d’écran : les annonces générées peuvent créer une expérience confuse et invasive, en se mêlant aux autres informations de contextualisation communiquées durant la saisie.
- Pour la plupart des personnes ayant des limitations : cela est susceptible d’interférer avec le rythme d’interaction et de saisie, qui est souvent plus lent que pour les personnes sans limitations.
Dans certains cas très spécifiques, une validation durant la saisie est parfois nécessaire. Le cas échéant, il importe d’adopter une approche la moins invasive possible.
Par exemple, pour un compteur de caractères, on privilégiera des rétroactions par paliers significatifs (moitié atteinte, dernier quart, etc.) plutôt qu’une mise à jour à chaque caractère. De même, un délai peut être prévu entre le moment où la saisie s’arrête et l’annonce de la rétroaction. Cela permet de maintenir l’utilisateur informé tout en évitant une surcharge d’informations.
Utiliser judicieusement les alertes et autres mentions de changement dynamique des contenus de la page
Dans les sections fonctionnelle et technique de cette fiche, nous avons vu l’importance de communiquer des messages d’état dans certains contextes de validation du formulaire. Toutefois, pour favoriser l’utilisabilité, ce critère d’accessibilité doit être intégré de manière non invasive.
Le composant proposé en exemple utilise une approche qui se limite à l’annonce des changements pertinents, afin de réduire la charge cognitive :
- Seule l’erreur nouvellement détectée à la sortie d’un champ est annoncée aux lecteurs d’écran, de même que sa numérotation (Erreur 1, Erreur 2, etc.);
- L’utilisateur peut déduire la progression de la correction via ce système de numérotation;
- Il n’y a pas de lecture intégrale de la liste des erreurs à chaque retrait ou apparition dynamique d’erreurs. À ce titre, il faut éviter de loger cette liste dans une zone d’alerte ou de type
aria-live
.
Nous avons relevé deux enjeux de la validation de formulaire avec certains outils d’adaptation. Ces problèmes sont causés par les outils eux-mêmes et demeurent à ce jour non résolus. Nous estimons que l’impact n’est pas suffisant pour renoncer à la présentation de l’exemple dans sa forme actuelle.
Avec JAWS : ordre d’annonce des erreurs à la sortie d’un champ
- Environnement d’observation : JAWS 2019 à 2025, avec les versions les plus récentes de Chrome, Edge et Firefox en date du 21 mars 2025.
- Résumé du problème : À la sortie d’un champ, les erreurs liées à ce champ sont mentionnées après la lecture du champ suivant (étiquette et type de champ en focus). L’utilisateur pourrait donc ne pas bien comprendre à quoi se rapporte l’erreur annoncée, ou même, ne pas entendre le texte de l’erreur. En effet, quand la lecture de l’étiquette du champ suivant est terminée, l’utilisateur peut commencer à écrire immédiatement, ce qui interrompt le message d’état.
- Comportement attendu : Les erreurs communiquées à la sortie d’un champ devraient être lues avant les informations du champ suivant.
- Pistes et analyses techniques : Le comportement se corrige dans JAWS (sous Firefox seulement) si le
<div>
dans lequel on injecte les messages d’erreurs utiliserole="alert"
. L’emploi dearia-live="assertive"
n’est pas suffisant. Les autres lecteurs d’écran (NVDA, VoiceOver iOS et Mac, Talkback) ne présentent pas ce problème. Ils priorisent l’annonce des erreurs en sortie du champ, peu importe l’emploi derole="alert"
ou dearia-live="assertive"
. - Impact estimé : Modéré. D’autres mécanismes de la validation de formulaire permettent de contrebalancer cet inconvénient (ex. : liste des erreurs).
- Décision : Ce bogue ne dépend pas spécifiquement de notre composant. Un suivi sera effectué auprès des équipes de développement de Freedom Scientific (JAWS) et Chromium (pour les navigateurs Chrome et Edge). Voir le ticket sur le profil GitHub de Freedom Scientific (en anglais).
Avec VoiceOver iOS : lecture des étiquettes de champ (<label>
)
- Environnement d’observation : Versions les plus récentes de VoiceOver iOS, Safari et Chrome en date du 21 mars 2025. Mode d’interaction tactile.
- Résumé du problème : Lorsqu’une étiquette (
<label>)
associée à un champ contient des éléments imbriqués (ex. :<span>
,<strong>
, etc.), la lecture par balayage gauche-droite (swipe) ignore systématiquement le dernier élément imbriqué dans l’étiquette. Cependant, une fois que le balayage atteint le champ associé, l’étiquette est relue au complet. - Comportement attendu : Lorsqu’une étiquette
<label>
n’a aucun élément imbriqué, le comportement usuel de VoiceOver iOS est de passer directement au champ lors du balayage, puis d’en lire l’étiquette associée. Cependant, quand il y a des éléments imbriqués dans le<label>
, le focus de VoiceOver iOS intercepte d’abord les contenus de l’étiquette. On s’attendrait à ce que tous les éléments de l’étiquette soient lus par le lecteur d’écran, car ignorer le dernier crée de la confusion. - Pistes et analyses techniques : Le problème de lecture partielle du
<label>
disparaît si le champ et l’étiquette ne sont plus associés informatiquement, ce qui renforce la thèse d’un bogue spécifique. Par ailleurs, le problème ne survient pas dans les légendes de groupe de champ. Diverses pistes de contournement, notamment du côté de la mise en forme CSS, ont été testées sans succès. - Impact estimé : Modéré. Même si l’enjeu est irritant, le libellé complet demeure présenté lorsque le focus atteint le champ.
- Décision : Ce bogue émane de VoiceOver iOS. Un suivi sera effectué auprès des équipes de développement de ce lecteur d’écran.
L’exemple se base sur le composant de validation de formulaire de la Boîte à outils de l’expérience Web (BOEW), version 4.0.81.1. Certains correctifs ont toutefois été apportés, notamment :
- Zone
aria-live
: Dans la version d’origine, les messages d’erreurs communiqués en temps réel sont injectés dans un<div>
auquel on assignearia-live="polite"
. Nous avons revu le paramétrage de cette zone en retirant l’attributaria-live
et en employant plutôtrole="alert"
, afin de prioriser l’annonce des erreurs à la sortie du champ concerné. Pour plus de détails, voir la section Enjeux connus avec les outils d’adaptation. - Mise en conformité avec certains critères applicables depuis les WCAG 2.1 :
- Critère 2.5.3 – Étiquette dans le nom (AA) : La version d’origine du composant applique
aria-hidden="true"
sur le libellé « obligatoire » de l’étiquette, dans l’objectif d’éviter une répétition d’information par les lecteurs d’écran. Cependant, cet ajout crée une non-conformité au critère « Étiquette dans le nom » et est susceptible de nuire aux personnes utilisatrices de commandes vocales. Nous avons retiré l’attributaria-hidden
au moyen d’un script d’appoint temporaire, d’ici à ce que la BOEW publie un correctif. - Critère 1.4.11 – Contraste du contenu non visuel (AA) : Un encadré de focus qui respecte ce critère est désormais utilisé. Il s’applique aux différents champs et boutons dont l’apparence au focus se limitait à une ombre portée sans contraste suffisant. Le nouvel encadré de focus respecte par ailleurs le critère 2.4.13 introduit dans les WCAG 2.2 : Apparence du focus (AAA).
- Critère 2.5.3 – Étiquette dans le nom (AA) : La version d’origine du composant applique
- Augmentation des contrastes de couleurs : Certaines teintes de rouge (bordures, icône d’alerte, etc.) ont été obscurcies pour les rendre encore plus perceptibles.