Le contrôle de saisie – Concevoir des formulaires accessibles

Par Mylène Boyrie, 25 mai 2022

Temps de lecture : 28 minutes

Mot(s) clé(s) :

Dans cette série, nous décryptons les techniques permettant de concevoir des formulaires accessibles et conformes au RGAA (Référentiel Général d’Amélioration de l’Accessibilité).Ce deuxième article s’attarde sur le contrôle de saisie, à savoir tout ce qui concerne le caractère obligatoire des champs, les types et formats de saisie attendus et les messages d’erreurs. Avant d’en commencer la lecture, je vous suggère de prendre connaissance de mon précédent article concernant les étiquettes de champ, dans lequel j’explique des notions mentionnées ci-après.

Sommaire

De quoi parle-t-on ?

Une fois encore, je vous propose un glossaire rapide des termes utilisés dans cet article et dans le RGAA, afin de faciliter la compréhension des critères et tests concernés.

Qu’est-ce que le contrôle de saisie ?

Lors de la conception d’un formulaire, en plus de la présence d’étiquettes sur chacun des champs, il faut préciser :

  • quels champs sont obligatoires,
  • lorsque nécessaire, quel est le type de données attendu et sous quel format il faut les saisir,
  • si les données saisies présentent des erreurs, quelles corrections doivent être apportées.

On parle alors de contrôle de saisie. Ces informations peuvent être précisées par la personne qui rédige les contenus, ou indiquées directement dans le code :

  • à l’aide d’attributs HTML (comme required pour indiquer qu’un champ est obligatoire),
  • avec des attributs WAI-ARIA (comme aria-required pour indiquer qu’un champ est obligatoire ou des passages de texte indiquant le format attendu et reliés aux champs par les attributs aria-labelledby ou aria-describedby),
  • via des types de champ indiquant automatiquement des indications de saisie ou d’erreurs (url, email, date,…).

Mettre en place un contrôle de saisie fonctionnel et documenté permet de faciliter l’utilisation d’un formulaire, et d’éviter à l’internaute tout bloquage lors de sa saisie. Nombre de formulaires sont aujourd’hui inaccessibles du fait d’aides à la saisie et messages d’erreur inexistants, incomplets, uniquement indiqués par la couleur ou encore non-reliés aux champs concernés. Les démarches des utilisateurices s’en trouvent ainsi compliquées, voire impossibles à effectuer. À l’heure où la numérisation de nos démarches en ligne se développe, il est primordial que toute information concernant le fonctionnement des formulaires soit explicite, complète et fonctionnelle.

La page d’accueil du site de la SNCF affiche un formulaire permettant de rechercher un trajet par numéro de train et date de départ.
La page d’accueil du site de la SNCF affiche un formulaire permettant de rechercher un trajet par numéro de train et date de départ. L’aide à la saisie est indiquée dans l’étiquette. Le champ Numéro de train est complété d’une infobulle reliée à celui-ci via l’attribut aria-describedby. Elle indique le format du numéro à saisir ainsi que sa provenance. Note : il y’a une coquille dans l’attribut – noté comme « aria_describedBy » au lieu de aria-describedby – la restitution aux lecteurs d’écran n’est donc pas fonctionnelle sur la page. Source : sncf.com.

L’indication de champ obligatoire

Cette indication à l’internaute de savoir quels champs sont obligatoires préalablement à la saisie d’un formulaire.

Elle peut être implémentée de différentes manières. La première consiste à indiquer le caractère obligatoire des champs de manière textuelle ou non textuelle :

  • en plaçant l’indication de champ obligatoire directement dans l’étiquette du champ,
  • en plaçant la mention « Tous les champs sont obligatoires » en début de formulaire, si tel est le cas,
  • il est également possible de fonctionner à rebours, en indiquant uniquement quels champs du formulaire sont facultatifs.
Le formulaire de contact de la Communauté Pays Basque affiche la mention « obligatoire » directement dans les étiquettes des champs concernés.
Le formulaire de contact de la Communauté Pays Basque affiche la mention « obligatoire » directement dans les étiquettes des champs concernés. Source : communaute-paysbasque.fr.

La seconde manière d’indiquer le caractère obligatoire d’un champ se passe côté code :

  • Grâce à l’attribut HTML required placé sur la balise du champ (<input>, <select>, <textarea>…) ;
  • Grâce à l’attribut WAI-ARIA aria-required, également placé sur la balise du champ,
  • Si l’indication visuelle du caractère obligatoire du champ n’est pas placée dans son étiquette, en associant celle-ci au champ via l’attribut WAI-ARIA aria-labelledby ou aria-describedby.

Quelle est la différence entre aria-labelledby et aria-describedby ?

Les attributs WAI-ARIA aria-describedby et aria-labelledby peuvent référencer plusieurs identifiants (id), qui seront ensuite concaténés par les technologies d’assistance, pour être restitués à leurs utilisateurices. Cependant, ces deux attributs ont chacun une finalité différente.

On l’a vu dans mon premier article « Labels visibles et noms accessibles, aria-labelledby est utilisé pour donner un nom accessible à un élément. S’il est présent, il prendra la place de l’intitulé visible de celui-ci. Il faut donc s’assurer que son utilisation et son contenu sont cohérents.

<p id="indication-obligatoire">Tous les champs sont obligatoires.</p>
<label for="surname">Prénom</label>
<input type ="text" id="surname" aria-labelledby="indication-obligatoire"/>

L’attribut aria-describedby vient quant à lui en complément du nom accessible, il ne le remplacera donc pas lors de la restitution.

Afin de corriger l’exemple précédent, j’ai remplacé l’attribut aria-labelledby par un attribut aria-describedby. L’étiquette du champ « Prénom » sera donc restituée, et suivie de la phrase « Tous les champs sont obligatoires. » référencée par l’attribut aria-describedby.

<p id="indication-obligatoire">Tous les champs sont obligatoires.</p>
<label for="surname">Prénom</label>
<input type ="text" id="surname" aria-describedby="indication-obligatoire"/>

Icônes, astérisques et autres caractères spéciaux

Malgré ce que j’entends parfois, la signification du signe « * » ne va pas de soi ! Lorsque le caractère obligatoire d’un champ est indiqué de manière non-textuelle (via la présence d’une icône ou d’un caractère spécial, par exemple), il faut toujours en expliciter la signification. Cette légende doit être visible et placée avant la première utilisation de l’indication non-textuelle dans le formulaire.

Le formulaire de contact du CERTAM affiche les champs obligatoires en plaçant un astérisque dans leurs étiquettes.
Le formulaire de contact du CERTAM affiche les champs obligatoires en plaçant un astérisque dans leurs étiquettes. Source : certam-avh.com.

L’indication du type de données et/ou de format

Cette indication permet à l’internaute de comprendre quel type de données et/ou format de saisie sont attendus dans un champ de formulaire, préalablement à sa saisie.

Cette aide à la saisie doit être visible et placée dans l’étiquette du champ ou dans un passage de texte relié à celui-ci via un attribut WAI-ARIA aria-labelledby ou aria-describedby. C’est pourquoi elle ne doit pas être placée dans l’attribut placeholder du champ. En effet, le contenu de l’attribut HTML placeholder disparaît lorsqu’on débute la saisie dans un champ. L’internaute perd alors le lien avec l’aide à la saisie.

Quelques exemples d’indication de format de données :

  • Adresse email (vous@domaine.com) ;
  • Code postal (format : 00000) ;
  • Date (format : JJ/MM/AAAA).
Le formulaire de connexion du site de la CAF indique la présence de contrôle de saisie dans l’attribut placeholder de ses champs.
Le formulaire de connexion du site de la CAF indique la présence de contrôle de saisie dans l’attribut placeholder de ses champs. Seul le champ « Numéro de Sécurité sociale » dispose d’un attribut title reprenant le contenu du placeholder. Le formulaire est donc inaccessible. Source : caf.fr.

Les messages d’erreur

Lorsqu’un formulaire présente des erreurs suite à son envoi, il faut toujours en indiquer les raisons afin de permettre à l’internaute de corriger sa saisie. Un message d’erreur peut indiquer l’absence de saisie d’un champ obligatoire, un format de données incorrect vis-à-vis de ce qui est attendu, ou tout autre information concernant la saisie du champ – par exemple un nom d’utilisateur n’existant pas dans la base de données.

Le formulaire d’inscription de Truffaut affiche des messages d’erreurs personnalisés.
Le formulaire d’inscription de Truffaut affiche des messages d’erreurs personnalisés. Il serait ici pertinent d’indiquer le format attendu dans le message d’erreur du champ E-mail, afin d’aider l’internaute à corriger sa saisie. Note : la mention « * Champs obligatoire » devrait être placée avant le premier champ obligatoire afin d’être conforme au RGAA. Source : truffaut.com.

Les messages de statut

Un message de statut informe l’internaute d’un changement de contenu dans la page sans interrompre son activité sur celle-ci. Ainsi, aucun changement de contexte n’est effectué – comme un repositionnement du focus par exemple.

Un message de statut peut informer sur :

  • Le succès ou le résultat d’une action ;
  • L’état occupé d’une application ;
  • L’état de progression dans un processus ;
  • L’existence d’erreurs.

Techniquement, ces messages sont signalés par un changement de role ou l’ajout d’une Live Region ARIA sur celui-ci (aria-live).

Ce que le RGAA 4.1 demande

Dix tests du RGAA 4.1 sont dédiés au contrôle de saisie, ils sont répartis sur trois critères différents. Pour chacun, je propose une explication de ce qui est attendu par le référentiel, ainsi que les notes et cas particuliers afférents.

Critère 11.10 [A] Dans chaque formulaire, le contrôle de saisie est-il utilisé de manière pertinente (hors cas particuliers) ?

Le critère 11.10 comprend pas moins de 7 tests contribuant à vérifier la conformité du contrôle de saisie d’un formulaire. Autant dire qu’il est touffu et demande un peu de décryptage.

Les champs obligatoires

Sa première exigence concerne la présence d’indications permettant de déterminer si un champ est obligatoire (tests 11.10.1 et 11.10.2). On l’a vu, il existe plusieurs manières pour y répondre :

  1. Placer une indication visible indiquant nommément quel champ est obligatoire. Cette indication peut être placée :
    1. à l’intérieur de l’étiquette du champ,
    2. hors de l’étiquette, dans un passage de texte relié au champ via l’attribut WAI-ARIA aria-labelledby ou aria-describedby,
    3. hors de l’étiquette, dans un passage de texte non relié au champ par du code. Dans ce cas, le champ concerné devra être identifiable nommément.
  2. OU indiquer le caractère obligatoire du champ dans le code, via l’attribut HTML required ou l’attribut WAI-ARIA aria-required. Dans ce cas, l’attribut choisi devra obligatoirement être complété d’une indication visible correspondant au point 1.
Cas particuliers

L’indication du caractère obligatoire des champs n’est pas exigée lorsque :

  • le formulaire comporte un seul champ,
  • le formulaire indique les champs optionnels de manière visible dans leurs étiquettes – ou dans les passages de texte associés via un attribut ARIA.

Instructions et indications de type et formats de données

La seconde exigence concerne les types et formats de saisie obligatoires. Dans le cas où un champ obligatoire impose un type et/ou un format de saisie, une indication du format attendu doit être visible et permettre, préalablement à la validation du formulaire, d’identifier le champ concerné (test 11.10.5).

Elle peut être placée directement dans l’étiquette du champ. Si ce n’est pas le cas, elle doit être reliée à celui-ci via l’attribut WAI-ARIA aria-labelledby ou aria-describedby,

Les messages d’erreur

La troisième exigence concerne la présence de messages d’erreurs lorsqu’un champ obligatoire n’a pas été saisi (tests 11.10.3 et 11.10.4) ou indique un type et/ou un format de données obligatoires non-respectés (tests 11.10.6 et 11.10.7). Dans ces cas, deux manières de procéder :

  1. Placer un message d’erreur visible et permettant d’identifier le champ concerné.
  2. Ajouter un attribut WAI-ARIA aria-invalid="true" au champ. Dans ce cas, le champ devra obligatoirement être complété d’un message d’erreur visible et placé dans son étiquette, ou relié via l’attribut WAI-ARIA aria-labelledby ou aria-describedby(ancre vers glossaire).

Correspondances WCAG 2.1

Critère 11.11 [AA] Dans chaque formulaire, le contrôle de saisie est-il accompagné, si nécessaire, de suggestions facilitant la correction des erreurs de saisie ?

Ce critère exige la présence d’indications permettant de corriger les erreurs de saisie, lorsque nécessaire. Pour répondre à cette exigence, les messages d’erreurs doivent indiquer :

  • Les types et les formats de données attendus,
  • Et/ou des exemples de valeurs attendues.

Correspondances WCAG 2.1

Critère 11.13 [AA] La finalité d’un champ de saisie peut-elle être déduite pour faciliter le remplissage automatique des champs avec les données de l’utilisateur ?

Ce dernier critère demande la présence d’un attribut autocomplete sur les champs concernant l’internaute (nom, prénom, date de naissance, coordonnées, etc.). Cet attribut doit être pourvu d’une valeur présente dans la liste des valeurs possibles et pertinente au regard du type d’information attendu.

Note : la liste des valeurs possibles pour l’attribut autocomplete repose sur les valeurs présentes dans la spécification WCAG 2.1 qui reprend elle-même la liste des valeurs de type « field name » de la spécification HTML5.2. Le critère WCAG demande à ce que l’une de ces valeurs soit présente pour qualifier un champ de saisie concernant l’utilisateur.

Correspondances WCAG 2.1

Exemples pratiques

Afin de vous aider à comprendre au mieux les possibilités de contrôles de saisie conformes au RGAA, j’ai conçu plusieurs exemples pour chacune des thématiques concernées (champs obligatoires, finalité des champs, aide à la saisie, messages d’erreur et aides à la correction). Pour chaque exemple, j’indique :

  • quels tests du RGAA 4.1 sont conformes ou non-applicables,
  • le cas échéant, les écueils soulevés par ces implémentations,
  • lorsque possible, la manière de corriger ou compléter ces exemples pour proposer une expérience de navigation la plus fluide et complète possible.

1 – Champs obligatoires

1.1 – Indiquer le caractère obligatoire du champ dans son étiquette

<label for="first-name">Prénom (obligatoire)</label>
<input id="first-name" type="text" name="first-name" autocomplete="given-name">

<label for="last-name">Nom (obligatoire)</label>
<input id="last-name" type="text" name="last-name" autocomplete="family-name">

Accéder au Codepen Required fields – Info in Label.

Dans cet exemple, le caractère obligatoire est indiqué en toutes lettres dans l’étiquette des champs, ce qui suffit à valider le test 11.10.1. Dans ce cas précis, le test 11.10.2 est non-applicable.

1.2 – Indiquer le caractère obligatoire du champ hors de son étiquette

Ces deux exemples s’appuient également sur la présence d’une indication visible pour valider le test 11.10.1 :

  • en identifiant nommément les champs obligatoires (exemple 1.2.1),
  • en reliant les champs à l’indication visible via l’attribut aria-describedby (exemple 1.2.2). Comme je l’expliquais en début d’article, je préfère son utilisation à celle de l’attribut aria-labelledby – qui sera pris en compte en tant qu’étiquette de champ dans le calcul du nom accessible. Si vous choisissez d’utiliser aria-labelledby : attention à reprendre le contenu de l’étiquette du champ dans l’attribut, afin de ne pas la supprimer lorsque le message d’erreur est affiché.

Dans ces deux cas également, le test 11.10.2 est non-applicable.

1.2.1 – Identifier nommément les champs
<p id="required-fields-info">Les champs Nom et Adresse email sont obligatoires.</p>

<label for="first-name">Prénom</label>
<input id="first-name" type="text" name="first-name" autocomplete="given-name">

<label for="last-name">Nom</label>
<input id="last-name" type="text" name="last-name" autocomplete="family-name">

<label for="email">Adresse email</label>
<input id="email" type="email" name="email" autocomplete="email">
1.2.2 – Relier le passage de texte via un attribut WAI-ARIA
<label for="first-name">Prénom</label>
<input id="first-name" type="text" name="first-name" autocomplete="given-name">

<label for="last-name">Nom</label>
<input id="last-name" type="text" name="last-name" autocomplete="family-name" aria-describedby="required-fields-nom">
<p id="required-fields-nom">Ce champ est obligatoire.</p>

<label for="email">Adresse email</label>
<input id="email" type="email" name="email" autocomplete="email" aria-describedby="required-fields-email">
<p id="required-fields-email">Ce champ est obligatoire.</p>

Accéder au Codepen Required fields – Info out of Labels.

1.3 – Combiner indication visible et attribut HTML required

<label for="first-name">Prénom (obligatoire)</label>
<input id="first-name" type="text" name="first-name" autocomplete="given-name" required>

<label for="last-name">Nom (obligatoire)</label>
<input id="last-name" type="text" name="last-name" autocomplete="family-name" required>

Accéder au Codepen Required fields – Visible indication and required attribute.

Cet exemple indique la présence de champs obligatoires via l’attribut HTML required placé sur les balises <input>. Si cet attribut suffit à valider le test 11.10.1, il rend cependant le test 11.10.2 applicable et nécessite donc d’être complété par une indication visible, placée ici dans les étiquettes de champs.

Cette combinaison est conforme au RGAA 4.1. Cependant elle déclenche une double restitution du caractère obligatoire des champs pour les internautes naviguant avec un lecteur d’écran :

  • La mention « obligatoire » sera restituée une première fois à la lecture de l’étiquette ;
  • Elle sera restituée une seconde fois à la prise de focus sur le champ en lui-même (la balise <input>), la synthèse vocale détectant la présence de l’attribut required ;
  • Note : l’utilisation de l’attribut aria-required aurait le même effet.
Exemple 1.3, restitution sous VoiceOver (vidéo)

Transcription de la vidéo

Combiner indication visible et attribut HTML required.

Prénom, obligatoire, vous êtes actuellement sur élément texte. Prénom, obligatoire, modifier le texte avec le menu de remplissage automatique.

Nom, obligatoire, vous êtes actuellement sur élément texte.. Nom, obligatoire, modifier le texte avec le menu de remplissage automatique.

Combiner indication visible et attribut HTML required (ou attribut WAI-ARIA aria-required) n’est donc pas recommandé, du fait de la lourdeur de la restitution.

1.4 – Combiner l’indication visible, l’attribut HTML required et l’attribut WAI-ARIA aria-hidden

Afin d’améliorer l’expérience des internautes naviguant avec un lecteur d’écran, on pourrait imaginer de compléter l’exemple précédent comme suit :

Exemple 1.4.1
<label for="first-name">Prénom <span class="required" aria-hidden="true">(obligatoire)<span></label>
<input id="first-name" type="text" name="first-name" autocomplete="given-name" required>

<label for="last-name">Nom <span class="required" aria-hidden="true">(obligatoire)<span></label>
<input id="last-name" type="text" name="last-name" autocomplete="family-name" required>
Exemple 1.4.2
<p class="required" aria-hidden="true">Les champs marqués d'un astérisque (*) sont obligatoires.</p>
<label for="first-name">Prénom <span class="aria-required" aria-hidden="true">*<span></label>
<input id="first-name" type="text" name="first-name" autocomplete="given-name" required>

<label for="last-name">Nom <span class="aria-required" aria-hidden="true">*<span></label>
<input id="last-name" type="text" name="last-name" autocomplete="family-name" required>

Accéder au Codepen Required fields: visible indication, required attribute and aria-hidden.

Dans ces versions, la présence de l’attribut WAI-ARIA aria-hidden="true" masque aux technologies d’assistance l’indication visible du caractère obligatoire présente dans les étiquettes. L’information concernant le caractère obligatoire est cependant toujours portée par la présence de l’attribut required (ou aria-required dans la version 2) sur les balises <input>, ce qui corrige le problème de double restitution rencontré dans l’exemple 1.3.

Exemple 1.4, restitution sous VoiceOver

Transcription de la vidéo

Niveau d’en-tête 2, trois éléments. Combiner indication visible et attribut HTML required– Exemple 1.4.1. Vous êtes actuellement sur élément texte.

Prénom, vous êtes actuellement sur élément texte. Prénom, obligatoire, modifier le texte avec le menu de remplissage automatique.

Nom, vous êtes actuellement sur élément texte. Nom, obligatoire, modifier le texte avec le menu de remplissage automatique.

Attention cependant, car cette implémentation peut potentiellement créer un souci de navigation pour les personnes utilisant le pilotage à la voix. En effet, selon la manière dont le contenu des étiquettes sera mis en forme, les internautes pourraient être amenés à énoncer le nom du champ de différentes manières.

Exemple 1.4.2.1

Exemple 1 : maquette de formulaire comprenant deux champs dont le caractère obligatoire est indiqué dans l'étiquette.

Dans cet exemple, le caractère obligatoire du champ est indiqué visuellement sur le même plan que son étiquette – même taille de texte, pas de hiérarchie de l’information via une mise en gras ou en italique, par exemple. L’internaute pourra ainsi avoir pour réflexe d’énoncer la totalité de l’étiquette visible pour se rendre sur le champ, soit « Adresse email (obligatoire) ». Or, si la mention « obligatoire » est masquée via l’attribut aria-hidden="true", la technologie d’assistance ne trouvera pas le champ correspondant.

Exemple 1.4.2.2

Exemple 2 : même maquette de formulaire, caractère ovligatoire distingué visuellement de l'étiquette.

Exemple 3 : même maquette de formulaire, caractère obligatoire placé hors des étiquette de champs.

Dans ces deux exemples, une hiérarchie de l’information est mise en place :

  • Dans l’exemple 1, la taille du nom du champ et celle du caractère obligatoire diffèrent. Le nom du champ prend visuellement le pas sur l’aspect obligatoire ;
  • Dans l’exemple 2, le caractère obligatoire est indiqué par la présence d’un astérisque, le nom du champ est donc également mis en avant.

Cette hiérarchie de l’information peut aider l’internaute à comprendre le fonctionnement de l’interface, on sera ainsi plus enclin à énoncer uniquement le nom du champ pour prendre le focus sur celui-ci, en se passant de son caractère obligatoire.

Ces modèles de conceptions seraient intéressants à proposer lors de tests utilisateurs, afin de vérifier les hypothèses et de décider de l’option la plus pertinente selon le contexte.

Second point d’attention : si ces exemples valident les tests 11.10.1 et 11.10.2, dans certains cas, ils pourront être considérés comme non conformes du point de vue du critère 10.8 du RGAA 4.1 concernant le masquage de contenus aux technologies d’assistance. La volonté de couvrir des contextes d’usage inconnus pourrait amener certain·es expert·es en accessibilité à ne pas vouloir prendre de risque et à invalider ce critère 10.8 face à ces exemples. En effet, des situations d’assistance dans « le monde réel » peuvent déclencher le problème de navigation décrit dans l’exemple 2.1 : par exemple, un service client décrivant une procédure en prenant pour référence l’«interface visible ».

Le contexte d’implémentation a donc son importance et demander conseil à un ou une experte en accessibilité pour décider de la marche à suivre sera préférable.

1.5 – Proposer une indication générique

Dans certains cas, il est pertinent d’indiquer le caractère obligatoire des champs d’un formulaire dans un message générique, placé au début de ce dernier :

  • lorsque tous les champs du formulaire sont obligatoires,
  • lorsque les champs obligatoires sont indiqués nommément dans le message générique (« Les champs X, Y et Z sont obligatoires »).
1.5.1 – Indication visible seule
<p class="required">Tous les champs sont obligatoires.</p>
<label for="first-name">Prénom</label>
<input id="first-name" type="text" name="first-name" autocomplete="given-name">

<label for="last-name">Nom</label>
<input id="last-name" type="text" name="last-name" autocomplete="family-name">

Accéder au Codepen Required fields: generic messages (with and without required attribute).

Dans cet exemple, la phrase « Tous les champs sont obligatoires » permet d’indiquer nommément les champs concernés – le test 11.10.2 est donc non-applicable.

Je réserverais cependant cet exemple aux formulaires contenant peu de champs, ce qui permet de conserver un lien visuel avec l’indication du caractère obligatoire et d’éviter de perturber les internautes ayant par exemple des problèmes de mémoire à court-terme ou des troubles de l’attention.

1.5.2 – Indication visible + attribut required
<p id="info-required">Tous les champs sont obligatoires.</p>
<label for="first-name">Prénom</label>
<input id="first-name" type="text" name="first-name" autocomplete="given-name" required aria-describedby="info-required">

<label for="last-name">Nom</label>
<input id="last-name" type="text" name="last-name" autocomplete="family-name" required aria-describedby="info-required">

Accéder au Codepen Required fields: generic messages (with and without required attribute).

Cet exemple complète le précédent par la présence de l’attribut required sur les balises <input>. Le test 11.2 est ici applicable et rendu conforme grâce à la phrase « Tous les champs sont obligatoires », reliée aux champs via l’attribut aria-describedby.

Attention cependant, la présence de l’attribut required couplée à celle de l’attribut aria-describedby renouvelle l’écueil rencontré dans l’exemple numéro 2, à savoir une double restitution du caractère obligatoire de chaque champ.

Second point d’attention, la restitution du caractère obligatoire des champs via l’attribut required permet de donner l’information aux internautes naviguant avec un lecteur d’écran uniquement. Afin de couvrir le maximum de contextes d’utilisation, je réserverais ici encore cet exemple à des formulaires ne demandant pas de scroll lors de la saisie, afin d’éviter la perte de lien visuel avec l’indication des champs obligatoires.

1.6 – Indiquer les champs facultatifs

Dans certains cas, il peut paraître plus évident d’indiquer les champs facultatifs, par exemple lorsque qu’un formulaire est principalement composé de champs obligatoires à l’exception de quelques-uns. Le RGAA décrit ces exemples dans sa gestion des cas particuliers et dans une note technique. Il existe ainsi deux possibilités d’implémentation des champs facultatifs.

1.6.1 – Indication des champs facultatifs – Formulaire court
<label for="first-name">Prénom (facultatif)</label>
<input id="first-name" type="text" name="first-name" autocomplete="given-name">

<label for="last-name">Nom</label>
<input id="last-name" type="text" name="last-name" autocomplete="family-name">

<label for="email">Email</label>
<input id="email" type="email" name="email" autocomplete="email">

Accéder au Codepen Indicating optional fields.

Dans le formulaire ci-dessus, le champ Prénom est indiqué en tant que champ facultatif, les deux autres champs sont obligatoires et indiqués comme tels de manière implicite. Cet exemple, décrit dans la gestion des cas particulier du RGAA, rend les tests 11.10.1 et 11.10.2 non applicables. Afin de répliquer ce cas particulier il faut :

  • Indiquer les champs optionnels de manière visible ;
  • Placer l’indication visible dans la balise <label>, dans le passage de texte associé au champ via l’attribut aria-labelledbyou aria-describedby ou dans la légende (balise <legend>) associée au groupe de champs (balise <fieldset>).
1.6.2 – Indication des champs facultatifs – Formulaire long

La note technique du critère 11.10 décrit un exemple différent de celui présenté dans la gestion des cas particuliers. Il correspondra plutôt à l’utilisation d’un long formulaire dont la majorité des champs est obligatoire. Si seuls les champs facultatifs sont explicitement indiqués comme tels, il faudra proposer :

  • Un message précisant que « tous les champs sont obligatoires sauf ceux indiqués comme étant facultatifs » ;
  • Une mention « facultatif » dans le libellé des champs, dans le passage de texte associé au champ via l’attribut aria-labelledbyou aria-describedby ou dans la légende du groupe de champs concernés ;
  • Un attribut required ou aria-required="true" associé à chaque champ obligatoire.
<p class="required">Tous les champs sont obligatoires, sauf ceux indiqués comme étant facultatifs.</p>
<label for="first-name">Prénom (facultatif)</label>
<input id="first-name" type="text" name="first-name" autocomplete="given-name">

<label for="last-name">Nom</label>
<input id="last-name" type="text" name="last-name" autocomplete="family-name" required>

<label for="email">Email</label>
<input id="email" type="email" name="email" autocomplete="email" required>

<label for="tel">Numéro de téléphone (facultatif)</label>
<input id="tel" type="tel" name="tel" autocomplete="tel">

<label for="mobile">Numéro de téléphone portable</label>
<input id="mobile" type="tel" name="mobile" autocomplete="tel" required>

<label for="address-01">Adresse postale</label>
<input id="address-01" type="text" name="address-01" autocomplete="address-line1" required>

<label for="address-02">Adresse postale – Complément</label>
<input id="address-02" type="text" name="address-02" autocomplete="address-line2" required>

<label for="cp">Code postal</label>
<input id="cp" type="number" name="code-postal" autocomplete="postal-code" required>

<label for="address-03">Ville</label>
<input id="address-03" type="text" name="address-03" autocomplete="address-line3" required>

Accéder au Codepen Indicating optional fields.

Note : cet exemple est présenté dans la note technique du critère 11.10 du RGAA. Puisque l’indication visuelle « Facultatif » est présente dans les étiquettes des champs, les tests 11.10.1 et 11.10.2 sont considérés comme non applicables.

On évite dans les deux exemples décrits ci-dessus l’écueil de la double restitution du caractère obligatoire des champs aux personnes naviguant avec un lecteur d’écran, ce qui peut constituer une alternative raisonnable. Cependant, ces systèmes demandent à l’internaute de déduire quels champs sont obligatoires, ce qui peut potentiellement présenter un problème pour les personnes ayant des troubles cognitifs ou une déficience intellectuelle. Ici encore, il faudra adapter le choix de conception au contexte et éventuellement les valider lors de tests utilisateurs.

2 – Finalité des champs

Aperçu d'un champ comprenant un attribut autocomplete email
Aperçu d’un champ comprenant un attribut autocomplete email.
<p>Les champs marqués d'un astérisque (*) sont obligatoires.</p>
<label for="email">Votre adresse email * (format : mail@exemple.com)</label>
<input id="email" name="email" type="text" autocomplete="email"/>

Accéder au Codepen HTML autocomplete attribute.

Dans l’exemple ci-dessus, la finalité du champ est indiquée par la présence de l’attribut HTML autocomplete="email". Sa présence permet d’indiquer aux agents utilisateurs quelle assistance à la saisie proposer aux internautes. La source de l’autocomplétion dépend des navigateurs.

Étrangement, on croise souvent cet attribut complété de la valeur off sur des champs se rapportant à des informations concernant les utilisateurices. Indiquer la valeur off au sein d’un attribut autocomplete revient à désactiver cette autocomplétion et à priver l’internaute d’une aide à la saisie précieuse car, dans ce cas, le navigateur n’est pas autorisé à saisir automatiquement des valeurs pour ce champ. Utiliser la valeur off est rarement pertinent, si l’on en croit les spécifications HTML 5.2 :

“The “off” keyword indicates either that the control’s input data is particularly sensitive (for example the activation code for a nuclear weapon); or that it is a value that will never be reused (for example a one-time-key for a bank login) and the user will therefore have to explicitly enter the data each time, instead of being able to rely on the UA to prefill the value for them; or that the document provides its own autocomplete mechanism and does not want the user agent to provide autocompletion values.”

Traduction : « Le mot-clef « off » indique :

  • soit que les données d’entrée de la commande sont particulièrement sensibles (par exemple le code d’activation d’une arme nucléaire) ;
  • ou qu’il s’agit d’une valeur qui ne sera jamais réutilisée (par exemple une clef à usage unique pour une connexion bancaire) et que l’utilisateurice devra donc saisir explicitement les données à chaque fois, au lieu de pouvoir compter sur l’agent utilisateur pour pré-remplir la valeur pour eux;
  • ou que le document fournit son propre mécanisme de saisie semi-automatique et ne souhaite pas que l’agent utilisateur fournisse des valeurs de saisie semi-automatique. »

Ajoutons que nombre de système d’autocomplétion personnalisés sont aujourd’hui inaccessibles, et dans certains cas entièrement remplaçables par l’attribut HTML autocomplete.

Ainsi, à moins d’entrer dans un des cas de figure listés par les specifications HTML 5.2, il n’y a aucune raison de ne pas indiquer un mot-clef pertinent en tant que valeur de l’attribut autocomplete pour aider l’internaute dans sa saisie.

Notons qu’il est également possible de construire une valeur composée pour l’attribut autocomplete. On peut ainsi obtenir une valeur de type autocomplete="shipping name" ou autocomplete="section-software shipping street-address". Les spécifications HTML 5.2 expliquent en détail les possibilités conformes au regard de l’algorithme.

3 – Aides à la saisie

3. 1 – Indiquer le format de données attendu dans l’étiquette du champ

<p class="controle-saisie">Tous les champs sont obligatoires</p>

<label for="first-name">Prénom</label>
<input id="first-name" type="text" name="first-name" autocomplete="given-name">

<label for="last-name">Nom</label>
<input id="last-name" type="text" name="last-name" autocomplete="family-name">

<label for="email">Votre adresse email (format : mail@exemple.com)</label>
<input id="email" name="email" type="email" autocomplete="email"/>

Accéder au Codepen Form instructions – Info in Label.

Dans cet exemple, le format de données attendu est indiqué dans l’étiquette du champ « Votre adresse email » et accompagné de la phrase « Tous les champs sont obligatoires », ce qui suffit à valider les tests 11.10.1 et 11.10.5. Le test 11.10.2 est ici non-applicable du fait de l’absence d’attribut required ou aria-required.

3. 2 – Indiquer le format de données attendu dans un passage de texte associé au champ

<p class="controle-saisie">Tous les champs sont obligatoires</p>

<label for="first-name">Prénom</label>
<input id="first-name" type="text" name="first-name" autocomplete="given-name">

<label for="last-name">Nom</label>
<input id="last-name" type="text" name="last-name" autocomplete="family-name">

<label for="email">Votre adresse email</label>
<input id="email" name="email" type="email" autocomplete="email" aria-describedby="controle-saisie"/>
<p id="controle-saisie">Format attendu : mail@exemple.com</p>

Accéder au Codepen Form instructions – Info out of Label.

Dans cet exemple :

  • le format de données attendu dans le champ « Votre adresse email » est indiqué dans un passage de texte relié au champ via l’attribut WAI-ARIA aria-describedby. Il sera restitué par les lecteurs d’écran à la prise de focus sur le champ.
  • le caractère obligatoire des champs est indiqué par la présence de la phrase « Tous les champs sont obligatoires ».

Les tests 11.10.1 et 11.10.5 sont conformes et ici encore, le test 11.10.2 est non-applicable du fait de l’absence d’attribut required ou aria-required.

3. 3 – Indiquer nommément le format de données attendu

<p>Les champs indiqués par un astérisque (*) sont obligatoires.</p>
<fieldset>
    <legend>Sélectionnez les dates de votre voyage (jj/mm/aaaa)</legend>

    <label for="date-depart">Date de départ *</label>
    <input id="date-depart" name="date-depart" type="date"/>

    <label for="date-retour">Date de retour *</label>
    <input id="date-retour" name="date-retour" type="date"/>
</fieldset>

Accéder au Codepen Form instructions – Info by name.

Dans cet exemple, le format attendu est indiqué dans la légende (balise <legend>) du regroupement des champs « Date de départ » et « Date de retour ». Le format attendu sera ainsi restitué à la prise de focus sur le regroupement de champs (balise <fieldset>), mais également à la prise de focus sur chaque champ qu’il contient. Le caractère obligatoire des champs est indiqué par la présence du caractère *, légendé au préalable.

Les tests 11.10.1 et 11.10.5 sont donc conformes et ici encore, le test 11.10.2 est non-applicable du fait de l’absence d’attribut required ou aria-required.

Point d’attention : champ de type date et compatibilité avec VoiceOver

Lors de mes tests sur cette portion de code, je me suis aperçue que les étiquettes de champs n’étaient pas restituées par VoiceOver (1), du fait de la présence de l’attribut type="date".

J’ai d’abord cru à un souci de compatibilité entre les navigateurs et certaines technologies d’assistance (2).

NVDA (3) ne montre aucun problème de restitution sur cette portion de code.

Le problème persiste cependant sur les deux dernières versions publiques de Safari (15.4 et 15.5), que l’on utilise Big Sur ou Monterey. Étrangement, un correctif a été appliqué sur Safari Preview Technology 145 (3), sans être pour autant reporté sur la version finale.

Tant que le correctif n’a pas été appliqué sur les dernières versions grand public de Safari, il vaut donc mieux éviter l’utilisation de l’attribut type="date" sur les champs de formulaire, afin d’éviter de proposer aux internautes utilisant VoiceOver des champs sans éituquettes.

4 – Messages d’erreurs

4. 1 – Proposer un message d’erreur indiquant nommément le champ

<p>Les champs indiqués par un astérisque (*) sont obligatoires.</p>
<fieldset>
    <legend>Sélectionnez les dates de votre voyage (jj/mm/aaaa)</legend>

    <label for="date-depart">Date de départ *</label>
    <input id="date-depart" name="date-depart" type="date"/>

    <label for="date-retour">Date de retour *</label>
    <input id="date-retour" name="date-retour" type="date"/>
</fieldset>
<p>Veuillez renseigner les champs Date de départ et Date de retour.</p>

<button type="submit">Rechercher un itinéraire</button>

Dans cet exemple, le message d’erreur :

  • indique nommément les champs concernés,
  • indique à nouveau le caractère obligatoire du champ.

Le test 11.10.3 est ainsi conforme. Le test 11.10.4 est ici non-applicable du fait de l’absence d’attribut aria-invalid="true".

Notons cependant que le message d’erreur ne sera pas immédiatement restitué aux internautes naviguant avec un lecteur d’écran, qui risqueront donc de passer à côté de l’information concernant les erreurs de saisie. Il existe plusieurs manières d’éviter cet écueil. Le RGAA propose par exemple dans le critère 7.5 de placer un attribut WAI-ARIA role="alert" sur les messages de statut avertissant de l’existence d’une erreur.

 <p>Les champs indiqués par un astérisque (*) sont obligatoires.</p>
 <fieldset>
     <legend>Sélectionnez les dates de votre voyage (jj/mm/aaaa)</legend>

     <label for="date-depart">Date de départ *</label>
     <input id="date-depart" name="date-depart" type="date"/>

     <label for="date-retour">Date de retour *</label>
     <input id="date-retour" name="date-retour" type="date"/>
 </fieldset>
 <p role="alert">Veuillez renseigner les champs Date de départ et Date de retour.</p>

 <button type="submit">Rechercher un itinéraire</button>

Accéder au Codepen Forms: user notifications by fields names.

Dans cette version corrigée, l’internaute reçoit l’information concernant les erreurs présentes dans le formulaire via le message de statut. Cependant, il lui faut naviguer à nouveau au début de celui-ci pour pouvoir corriger les champs correspondants.

4.2 – Proposer le message d’erreur dans un passage de texte associé au champ

 <p>Les champs indiqués par un astérisque (*) sont obligatoires.</p>
 <fieldset>
     <legend>Sélectionnez les dates de votre voyage (jj/mm/aaaa)</legend>

     <label for="date-depart">Date de départ *</label>
     <input id="date-depart" name="date-depart" type="date" aria-describedby="msg-erreurs"/>

     <label for="date-retour">Date de retour *</label>
     <input id="date-retour" name="date-retour" type="date" aria-describedby="msg-erreurs"/>
 </fieldset>
 <p id="msg-erreurs">Veuillez renseigner les champs Date de départ et Date de retour.</p>

 <button type="submit">Rechercher un itinéraire</button>

Accéder au Codepen Forms: error messages with ARIA.

Une autre manière de corriger le problème de non-restitution des erreurs détaillé dans l’exemple précédent est :

  • de relier le message d’erreur aux champs correspondants via un attribut aria-describedby,
  • de repositionner le focus sur le premier champ erroné lorsque le formulaire génère une erreur.

Dans cet exemple, le parcours utilisateur serait donc le suivant :

  1. l’internaute omet de remplir deux champs obligatoires et active le bouton Rechercher un itinéraire,
  2. le formulaire génère un message d’erreur,
  3. le focus est replacé sur le champ « Date de départ »,
  4. le lecteur d’écran restitue le message d’erreur à l’internaute grace à la présence de l’attribut aria-describedby faisant référence à l’ID du message d’erreur,
  5. l’internaute peut immédiatement corriger la saisie erronée plutôt que d’avoir à naviguer à nouveau au début du formulaire pour trouver les champs correspondants.

La navigation est ici plus fluide et évite à l’internaute de devoir se souvenir des champs erronés listés dans le message de statut, comme dans l’exemple précédent.

Ici encore, le test 11.10.3 est conforme et le test 11.10.4 est non-applicable du fait de l’absence d’attribut aria-invalid="true".

4. 3 – Combiner le message d’erreur visible et l’attribut WAI-ARIA aria-invalid

 <p>Les champs indiqués par un astérisque (*) sont obligatoires.</p>
 <fieldset>
     <legend>Sélectionnez les dates de votre voyage (jj/mm/aaaa)</legend>

     <label for="date-depart">Date de départ *</label>
     <input id="date-depart" name="date-depart" type="text" aria-invalid="true" aria-describedby="msg-erreurs"/>

     <label for="date-retour">Date de retour *</label>
     <input id="date-retour" name="date-retour" type="text" aria-invalid="true" aria-describedby="msg-erreurs"/>
 </fieldset>
 <p id="msg-erreurs">Veuillez renseigner les champs Date de départ et Date de retour.</p>

 <button type="submit">Rechercher un itinéraire</button>

Accéder au Codepen Forms: error messages + aria-invalid.

Dans cet exemple, la présence d’erreurs de saisie est signalée par l’attribut WAI-ARIA aria-invalid. L’ajout d’aria-invalid aux champs concernés permet de valider le test 11.10.3, mais il rend applicable le test 11.10.4 et nécessite donc d’être complété par une indication visible.

Ce message visible peut être placé :

  • dans les étiquettes de champs – cas de figure assez rare,
  • dans un/des passage(s) de texte relié(s) aux champs concernés via un attribut aria-describedby – c’est le cas dans cet exemple.

Cette version est conforme au RGAA 4.1, mais elle déclenche ici encore une double restitution de la présence d’erreurs de saisie pour les internautes naviguant avec un lecteur d’écran :

  • La mention « données invalides » sera restituée une première fois lors de la navigation, du fait de la présence d’aria-invalid.
  • Elle sera restituée une seconde fois lors de la lecture du passage de texte associé au champ via l’attribut aria-describedby.

Notons que l’information restituée par aria-invalid diffère selon le lecteur d’écran et le navigateur utilisés, et qu’il n’est à l’heure actuelle pas possible de personnaliser le message d’erreur généré. La spécification ARIA devrait être complétée dans le futur concernant aria-invalid, cependant nous ne recommandons à l’heure actuelle pas son utilisation. Les méthodes présentées dans les exemples précédents suffisent en effet à valider le test 11.10.3 tout en proposant une expérience de navigation fluide et compréhensible.

4.4 – Proposer un message d’erreur générique en début de formulaire

Dans cet exemple, les erreurs de saisies sont listées en début de formulaire. La phrase « Veuillez renseigner les questions 1, 5, 6 et 7. » :

  • indique nommément les champs concernés,
  • indique à nouveau le caractère obligatoire du champ,
  • est complétée par un attribut role="alert permettant de restituer l’information aux internautes utilisant un lecteur d’écran.
<h2>Formulaire long – Erreurs listées au début</h2>
<form>
    <p>Tous les champs sont obligatoires.</p>
    <p role="alert">Veuillez renseigner les questions 1, 5, 6 et 7.</p>
    <fieldset class="qcm">
        <legend>Question 1 : en quelle année Ada Lovelace a-t'elle créé le premier programme destiné à être exécuté par une machine ?</legend>
        <div class="radio">
            <input type="radio" name="ada" id="1841" value="1841" />
            <label for="1841">1841</label>
        </div>
        <div class="radio">
            <input type="radio" name="ada" id="1842" value="1842" />
            <label for="1842">1842</label>
        </div>
        <div class="radio">
            <input type="radio" name="ada" id="1843" value="1843" />
            <label for="1843">1843</label>
        </div>
    </fieldset>

    <fieldset class="qcm">
        <legend>Question 2 : quelle avancée technologique a été créée par Karen Spärck Jones ?</legend>
        <div class="radio">
            <input type="radio" name="karen" id="td-idf" value="td-idf" />
            <label for="td-idf">L’algorithme à la base de nos moteurs de recherche (TF-IDF)</label>
        </div>
        <div class="radio">
            <input type="radio" name="karen" id="zipf" value="zipf" checked />
            <label for="zipf">La loi de Zipf</label>
        </div>
        <div class="radio">
            <input type="radio" name="karen" id="boole" value="boole" />
            <label for="boole">Le modèle booléen</label>
        </div>
    </fieldset>

    <div class="question">
        <label for="easley">Question 3 : dans quelle organisation Annie Easley travailla-t'elle ? </label>
        <input id="easley" type="text" name="easley" value="NASA">
    </div>

    <fieldset class="qcm">
        <legend>Question 4 : que doit-on à Grace Hopper ?</legend>
        <div class="checkbox">
            <input type="checkbox" name="hopper" id="compil" value="compil" />
            <label for="compil">Le compilateur</label>
        </div>
        <div class="checkbox">
            <input type="checkbox" name="hopper" id="bug" value="bug" checked/>
            <label for="bug">Elle a identifié le premier bug informatique</label>
        </div>
        <div class="checkbox">
            <input type="checkbox" name="hopper" id="wifi" value="wifi" checked/>
            <label for="wifi">Elle a inventé le Wifi</label>
        </div>
    </fieldset>

    <div class="question">
        <label for="wcb">Question 5 : dans quelle organisation Annie Easley travailla-t'elle ? </label>
        <input id="wcb" type="text" name="wcb" value="">
    </div>

    <fieldset class="qcm">
        <legend>Question 6 : quel projet la programmeuse Margaret Hamilton a-t'elle  mis au point ?</legend>
        <div class="radio">
            <input type="radio" name="hamilton" id="td-idf" value="td-idf" />
            <label for="td-idf">ENIAC, le premier ordinateur électronique</label>
        </div>
        <div class="radio">
            <input type="radio" name="hamilton" id="bombe" value="bombe" />
            <label for="bombe">Bombe, une machine décodant les messages secrets allemands pendant la Seconde Guerre Mondiale</label>
        </div>
        <div class="radio">
            <input type="radio" name="hamilton" id="appollo" value="appollo" />
            <label for="appollo">Le système informatique destiné à guider le vaisseau d'Apollo 8</label>
        </div>
    </fieldset>
    <button type="submit"></button>
</form>
<h3>Sources (et pour en savoir plus sur le sujet) : </h3>
<ul>
    <li><a href="<https://www.womenintech.co.uk/10-famous-women-technology-changed-world>">10 of the Most Famous Women in Technology who Changed the World</a>, Women in tech</li>
    <li><a href="<https://www.zerodeux.fr/interviews/computer-grrrls/>">Computer Grrrls – Entretien avec Marie Lechner</a>, par Aude Launay</li>
    <li><em lang="en">Broad Band, the untold story of the women who made the Internet</em>, par Claire L. Evans – Portfolio / Penguin</li>
    <li><a href="<https://www.journaldugeek.com/dossier/dada-lovelace-a-karen-spark-jones-petite-revue-femmes-pionnieres-linformatique/>">D’Ada Lovelace à Karen Spärck Jones, petite revue des femmes pionnières dans l’informatique</a>, par Camille Suard</li>
</ul>

Accéder au Codepen Form instructions – Generic message.

La présence du message de statut permet de valider le test 11.10.3 et le critère 7.5. Le test 11.10.4 est non-applicable du fait de l’absence d’attribut aria-invalid="true".

Le formulaire étant très long, le défilement vers le bas déclenche une perte de lien visuel avec le message de statut.On peut donc imaginer de compléter cette interface en plaçant une indication visuelle – par exemple un pictogramme – à proximité de l’étiquette de chaque champ ou regroupement de champ à corriger. Dans ce cas, il faudra s’assurer que l’image possède un attribut alt pertinent, puisqu’elle porte une information. On pourra également compléter celle-ci d’une infobulle ou étiquette visible – notamment pour éviter aux personnes naviguant avec une loupe d’écran d’en chercher la signification.

(maquette)

5 – Messages d’erreurs + suggestions de corrections

Ces cas de figure concernent les messages d’erreur fournissant une instruction ou une indication au sujet :

  • du type de données attendues,
  • du format obligatoire de saisie.

Dans ces cas, ces indications doivent être visibles et identifier le ou les champs concernés. L’utilisation de l’attribut aria-invalid est ici encore techniquement possible, mais on rencontre les mêmes inconvénients que pour les messages d’erreurs « classiques », à savoir une double restitution de l’information du fait de l’impossibilité de personnaliser les messages restitués par la présence de aria-invalid. Nous ne recommandons donc pas son utilisation.

5.1 – Indiquer à nouveau le format attendu

Le RGAA suggère deux manières de gérer la présence d’aide à la saisie dans les messages d’erreur. La première revient à préciser de nouveau le type ou format de données attendu, ce qui valide le test 11.11.1.

<p id="controle-saisie">Tous les champs sont obligatoires</p>

<label for="first-name">Prénom</label>
<input id="first-name" type="text" name="first-name" autocomplete="given-name">

<label for="last-name">Nom</label>
<input id="last-name" type="text" name="last-name" autocomplete="family-name">

<label for="email">Votre adresse email (format : mail@exemple.com)</label>
<input id="email" name="email" type="email" autocomplete="email" aria-describedby="message-erreur" value="biduleàyopmail.com" />
<p id="msg-erreur">Le format de votre adresse email est erroné. Pour le corriger, indiquer une adresse email correspondant au format mail@exemple.com.</p>

Accéder au Codepen Form errors and instructions: required format.

Les modèles de conception décrits dans les exemples précédents restent valables implémenter cette solution. Cependant, il n’est pas certain que la répétition d’une information identique soit des plus judicieuses pour aider l’internaute à corriger sa saisie.

5.2 – Proposer un exemple de valeur attendue

La seconde solution revient à proposer à l’internaute un exemple de saisie, ce qui permet de valider le test 11.11.2.

<p id="controle-saisie">Tous les champs sont obligatoires</p>

<label for="first-name">Prénom</label>
<input id="first-name" type="text" name="first-name" autocomplete="given-name">

<label for="last-name">Nom</label>
<input id="last-name" type="text" name="last-name" autocomplete="family-name">

<label for="email">Votre adresse email (format : mail@exemple.com)</label>
<input id="email" name="email" type="email" autocomplete="email" aria-describedby="message-erreur" value="biduleàyopmail.com" />
<p id="msg-erreur">Le format de votre adresse email est erroné. Pour le corriger, indiquer une adresse email correspondant au format attendu. Par exemple : daniel.defoe@outlook.fr</p>

Accéder au Codepen Form errors and instructions: providing examples for required format.

Cette solution permet de donner un supplément d’information aux utilisateurices, en illustrant concrètement le type de données et/ou le format attendus.

5.3 – Proposer une aide à la saisie grâce à l’attribut HTML type

Certains types de contrôles HTML5 proposent des messages d’aide à la saisie automatiques. Par exemple le type email affiche un message du type « veuillez saisir une adresse e-mail valide » dans le cas où l’adresse e-mail saisie ne correspond pas au format attendu. Ces messages sont personnalisables via l’API Constraint Validation, ce qui permet de personnaliser les messages d’erreur et de valider le critère 11.11.

Vous trouverez plus de détails sur l’implémentation de l’API Constraint Validation et un exemple fonctionnel sur mdn web docs.

5.4 – Proposer une aide à la saisie grâce à l’attribut HTML pattern

L’attribut HTML pattern permet quant à lui d’effectuer automatiquement des contrôles de format via des expressions régulières (regexp) sur les champs de type text, tel, email, url, password et search. Lorsque le format attendu ne correspond pas à la saisie, on peut afficher un message d’aide personnalisable via un attribut title : ce dispositif valide également le critère 11.11.

Vous trouverez des exemples fonctionnels de l’utilisation de l’attribut pattern pour afficher des messages d’erreurs sur mdn web docs.

Ce dispositif ne couvre cependant pas tout le champ des possibles, car l’utilisation de l’attribut title sur les champs de formulaires n’est pas accessible à tout le monde. On pourra envisager de le compléter par un message d’aide visible. Ce fesant, on retombera dans l’écueil de la double restitution aux utilisateurices de lecteurs d’écrans et rendant simultanément l’utilisation de l’attribut pattern inutile.

6 – Messages d’erreurs + title de la page

Dans le cas où un formulaire présente des erreurs après un rechargement de la page, il est pertinent de l’indiquer dans le titre (balise <title></title>) de celle-ci. En effet, mettre à jour l’intitulé de la page permet aux internautes d’être prévenu·es des erreurs présentes dans le formulaire avant même d’entrer dans son contenu.

<!DOCTYPE html>
<html lang="fr">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Contactez-nous, le formulaire présente 1 erreur de saisie – Nom du site</title>
</head>
<body>

<h2>6 – Messages d'erreurs + <code>title</code> de la page</h2>

<p id="controle-saisie">Tous les champs sont obligatoires</p>

<label for="first-name">Prénom</label>
<input id="first-name" type="text" name="first-name" autocomplete="given-name">

<label for="last-name">Nom</label>
<input id="last-name" type="text" name="last-name" autocomplete="family-name">

<label for="email">Votre adresse email (format : mail@exemple.com)</label>
<input id="email" name="email" type="email" autocomplete="email" aria-describedby="message-erreur" value="biduleàyopmail.com" />
<p id="msg-erreur">Le format de votre adresse email est erroné. Pour le corriger, indiquer une adresse email correspondant au format attendu. Par exemple : daniel.defoe@outlook.fr</p>
</body>
</html>

Accéder au Codepen Form errors and instructions: providing examples for required format.

À retenir

Comment implémenter le contrôle de saisie de manière accessible ?

Le caractère obligatoire des champs

  1. Toujours indiquer de manière visible le caractère obligatoire d’un champ, si possible directement dans son étiquette ;
  2. La présence d’un attribut required ou aria-required n’est pas obligatoire :
  3. La présence d’une icône ou d’un astérisque doit toujours être légendée. L’explication doit être placée en amont du formulaire ;
  4. Si l’indication du caractère obligatoire d’un champ n’est pas placée dans son étiquette, elle doit être reliée à celui-ci via un attribut aria-labelledby ou aria-describedby.

Instructions et indications de type et formats de données

  1. Lorsque le format de saisie est imposé, toujours indiquer de manière visible le type et/ou format de données attendu, si possible directement dans l’étiquette du champ concerné ;
  2. Si l’indication du type/ou format de saisie d’un champ n’est pas placée dans son étiquette, elle doit être reliée à celui-ci via un attribut aria-labelledby ou aria-describedby.
  3. Les champs concernant des informations liées aux utilisateurices doivent disposer d’un attribut autocomplete pertinent.

Les messages d’erreur

  1. Lorsqu’un champ obligatoire n’est pas rempli ou lorsqu’un format de données obligatoire n’est pas respecté, toujours afficher un message d’erreur.
  2. Le message d’erreur doit être visible et permettra d’identifier le champ, par exemple en le plaçant directement dans son étiquette, ou en le reliant à celui-ci via l’attribut WAI-ARIA aria-labelledby ou aria-describedby;
  3. La présence d’un attribut aria-invalid=”true”n’est pas obligatoire.
  4. L’utilisation de messages de statuts peut être pertinente, dans le cas où certaines informations (champs obligatoires, erreurs, aide à la saisie) sont placée en début ou fin de formulaire – leur utilisation fera l’objet d’un article à part entière.
  5. Modifier la balise <title> de la page en indiquant que le formulaire comporte des erreurs permets aux utilisateurices utilisant un lecteur d’écran d’en être informé avant même d’entrer dans le contenu ce celle-ci.

Notes

  1. VoiceOver : lecteur d’écran présent sur tous les appareils utilisant Mac OS et iOS – Retour au texte ↑
  2. Is input type=“date” ready for use in accessible websites?, de Graham Armfield – février 2019 (en anglais) – Retour au texte ↑
  3. NVDA : lecteur d’écran open source pour Windows, disponible sur nvaccess.orgRetour au texte ↑
  4. Safari Preview Technology : version du navigateur Safari dédiées aux développeuses et développeurs, disponible sur developer.apple.com/safari/technology-preview/ Retour au texte ↑