Exemples de formulaire

Préambule

Pour qu’un formulaire soit accessible à l’ensemble des utilisateurs, quelques règles doivent être respectées lors du développement. C’est ce que nous allons voir en détail dans l’exemple de formulaire accessible.

Exemple de formulaire accessible

Dans cet exemple, nous avons utilisé la librairie Boosted. Celle-ci permet d’obtenir des formulaires dont le design est conforme à la charte Orange. Nous utilisons également du javascript pour les contrôles de saisie.

Couleur

Numéro de série commençant par « TS- » suivi de 4 chiffres.

Mise en place

Étiqueter les champs de formulaire

Tous les éléments de formulaire doivent être étiquetés avec un libellé pertinent, donc qui, spécifiquement, informe sur le contenu attendu dans le champ, le bouton, le bouton radio la case à cocher ou la liste déroulante. Ainsi, le lecteur d’écran vocalisera automatiquement le libellé du champ de formulaire lors de la sélection de l'élément de formulaire lors de la navigation.

De plus, les étiquettes (label) doivent être le moins possible éloignées visuellement de leur champ afin de faciliter leur association (notamment par les malvoyants, déficients cognitifs, les utilisateurs ayant des troubles de l'attention ou de la concentration).

Il existe plusieurs solutions pour étiqueter un champ de formulaire (autre qu'un bouton).

Utilisation d’une balise label

Il s’agit de la solution standard, à utiliser en priorité, pour étiqueter un champ de formulaire, la mieux supportée par les outils d’assistance.

Utiliser une balise label et renseigner son attribut for avec l’id du champ de formulaire auquel elle est associée. C’est important pour les utilisateurs de lecteurs d’écran, mais cela permet également d’améliorer l’ergonomie du formulaire. En effet, lorsque le label est correctement associé à son champ de formulaire, il devient possible de cocher une case à cocher ou de sélectionner un bouton radio en cliquant directement sur son label et vu la taille par défaut de ces éléments, c'est bien pratique.


        <input type="checkbox" id="cgu">
        <label for="cgu">Veuillez accepter les <abbr>CGU</abbr>.</label>
  

Dans de rares cas, il peut s’avérer qu’il ne soit pas nécessaire d’afficher un libellé car sa fonction est grâce au contexte, évidente (champ de recherche proche du bouton avec l'icône loupe, la case à cocher pour sélectionner une ligne de tableau, par exemple). Prévoir tout de même un libellé pour les lecteurs d’écran et le masquer en utilisant une des 3 méthodes suivantes.

Classe CSS de masquage accessible

C’est la méthode utilisée sur le second champ de saisie de l’adresse dans cet exemple de formulaire accessible (utilisation de la classe visually-hidden de Bootstrap/Boosted).

Code CSS


  .visually-hidden {
        position: absolute;
        width: 1px;
        height: 1px;
        padding: 0;
        margin: -1px;
        overflow: hidden;
        clip: rect(0, 0, 0, 0);
        white-space: nowrap; /* added line */
        border: 0;
  }
  

Code HTML


  <label for="adresse">Adresse *</label>
  <input name="adresse" data-displayname="adresse" class="form-control" id="adresse" aria-required="true" type="text">
  <label class="visually-hidden" for="complement">Complément d’adresse</label>
  <input class="form-control" id="complement" type="text">
  

L’utilisation du masquage accessible permet de masquer l’élément à l’écran tout en conservant sa vocalisation par les outils ou technologies d’assistance (AT). Attention, ne pas utiliser du masquage CSS classique (display: none; ou visibility: hidden;) car l’élément sera masqué également pour les lecteurs d’écran.

Consultez l’exemple sur le masquage accessible pour plus l’information.

Utilisation d’un attribut title

L’attribut title n’est pas suffisamment robuste utile pour l’accessibilité sauf dans ce cas précis, en permettant d’étiqueter un champ de formulaire de manière accessible. Il déclenchera également l’affichage d’une info-bulle au survol de l’élément avec la souris, bonne chose pour les déficients cognitifs, les malvoyants.


  <input type="text" title="Rechercher dans le catalogue">
  

À noter : l’attribut title positionné ailleurs que sur un champ de formulaire (par exemple sur une image) ne fournit aucune garantie que son contenu sera vocalisé par un lecteur d’écran.

Utilisation d’attributs ARIA aria-label ou aria-labelledby

Les attributs aria-label et aria-labelledby peuvent être utilisés pour étiqueter des champs de formulaire et leur support est bon dans les navigateurs et dans les AT récentes :


  <span id="label-adress">Adresse *</span>
  <input type="text" aria-labelledby="label-adress">
  <input type="text" aria-label="complément d’adresse">
  

Le placeholder et le label

L’attribut placeholder ne peut pas être utilisé à la place d’un label. En effet :

En revanche, le placeholder peut servir de guide, d’aide pour remplir le champ sans que cette information soit absolument nécessaire (par exemple, proposer une valeur attendue valide) : ne pas hésiter à l’utiliser pour ce type de besoin.


  <div class="mb-3">
        <label for="numero-serie">Veuillez saisir le numéro de série *</label>
        <input type="text" name="serie" data-displayname="numéro de série" class="form-control" id="numero-serie" aria-describedby="helpblock"
        aria-required="true" placeholder="exemple : TS-0000">
  </div>

Utilisation de l'attribut autocomplete

Pour tout champ dont le type est listé dans 7. Input Purposes for User Interface Components, il faut remplir l'attribut autocomplete du champ avec la valeur adéquate.


  <div class="mb-3">
        <label for="lname">Nom de famille :</label>
        <input id="lname" type="text" autocomplete="family-name" class="form-control">
        <label for="cc-num">Numéro de carte de crédit :</label>
        <input type="text" id="cc-num" autocomplete="cc-number" class="form-control">
  </div>

Préciser les champs obligatoires

Il faut, bien sûr, clairement indiquer pour tout utilisateur le fait qu’un champ soit obligatoire. Ceci en utilisant un signe distinctif (mention, pictogramme, image, etc.) mais aussi avec un simple texte (par exemple, « obligatoire ») dans le label du champ. Ajouter, si besoin, une mention au début du formulaire pour indiquer que le symbole ou le pictogramme en question signale un champ obligatoire.

Les champs obligatoires doivent aussi être indiqués dans le code à l’aide de l’attribut HTML5 required ou de l’attribut ARIA aria-required notamment pour les déficients visuels. Leur support par les AT est maintenant suffisant pour que l'on utilise indifféremment l'un ou l'autre mais pas les deux en même temps.


<input type="text" name="telephone" required>
<input type="text" name="telephone" aria-required="true">

Cas particulier des radio-boutons obligatoires

Pour indiquer à un utilisateur d'AT qu'une série de radio-boutons est obligatoire, vous pouvez tout à fait ajouter un aria-required="true" ou un required sur chacun d'entre eux. Cependant, une autre solution est envisageable, utiliser le role="radiogroup" sur l'élément contenant les radio-boutons. Ici, on utilise, en plus, un aria-labelledby afin de donner une étiquette (nom accessible) pertinente à ce radiogroup.


<p id="radio1-desc">Choisissez une couleur de T-shirt.</p>
<div role="radiogroup" aria-required="true" aria-labelledby="radio1-desc">
  <input type="radio" name="radio1" id="radio1-0">
  <label for="radio1-0">Votre T-shirt en rouge</label>
  <input type="radio" name="radio1" id="radio1-1">
  <label for="radio1-1">Votre T-shirt en bleu</label>
</div>

Préciser le type ou le format attendu

Lorsque c’est nécessaire, préciser pour tous les utilisateurs, dans le label du champ, le type ou le format de la donnée attendu. Pour que cette information soit vocalisée automatiquement par les lecteurs d’écran, vous préférerez mettre ces informations directement dans la balise label ; sinon utiliser un attribut aria-describedby pour référencer du texte visuellement présent dans la page mais hors du label.


<div class="mb-3">
      <label for="numero-serie">Veuillez saisir le numéro de série *</label>
      <input type="text" id="numero-serie" aria-describedby="helpblock" aria-required="true">ll
</div>
<span id="helpblock" class="help-block">Numéro de série commençant par "TS-" suivi de 4 chiffres (exemple: "TS-4521").</span>

L'étiquette visuelle du champ et son nom (accessible)

On peut modifier le nom accessible d'un élément de formulaire, donc ce qui sera restitué aux AT, pour en savoir plus sur le nom accessible en HTML. Cependant, il ne faut pas que des éléments dont on a modifié le nom accessible soit différents de l'étiquette/intitulé affiché car cela empêche leur utilisation pour des AT de commande vocale notamment. Le nom accessible et l'étiquette/intitulé doivent avoir des valeurs identiques ou, au moins, le texte de l'étiquette/intitulé doit commencer par la valeur du nom accessible.

Déplacer le focus automatiquement lors de l'apparition d'un nouveau champ

Il est parfois tentant, lors de l'activation d'un champ spécifique (par exemple, un bouton radio "Autre, précisez..."), de faire apparaître un nouveau champ tout en y mettant le focus automatiquement. C'est problématique en ce qui concerne l'accessibilité à deux égards :

Regrouper les informations de même nature

Les champs de même nature doivent être regroupés, si nécessaire (champs ayant la même étiquette ou étiquette insuffisante à elle seule pour comprendre quelles données entrer), à l’aide d’une balise fieldset. Le fieldset doit également posséder comme premier enfant une légende explicite (balise legend). Le fieldset/legend est nécessaire, notamment, lorsque la légende est utile à la compréhension ou l’individualisation (différencier des label identiques dans un même formulaire) des balises label incluses dans le fieldset.


<fieldset>
      <legend>Couleur du capot de votre téléphone</legend>
      <input type="radio" name="couleur" id="blanc" checked>
      <label for="blanc">Blanc</label>
      <input type="radio" name="couleur" id="noir">
      <label for="noir">Noir</label>
</fieldset>

<fieldset>
      <legend>Adresse de livraison</legend>
      <label for="nom">Contact</label>
      <input type="text" id="nom">
      <label for="adresse">Adresse</label>
      <input type="text" id="adresse">
      <label for="ville">Ville</label>
      <input type="text" id="ville">
</fieldset>

<fieldset>
      <legend>Adresse de facturation</legend>
      <label for="nom1">Contact</label>
      <input type="text" id="nom1">
      <label for="adresse1">Adresse</label>
      <input type="text" id="adresse1">
      <label for="ville1">Ville</label>
      <input type="text" id="ville1">
</fieldset>

Cas particulier d'une même donnée ventilées dans plusieurs champs

Par exemple, pour entrer une date sous forme de 3 champs, un pour le jour, un pour le mois et un pour l’année, voici une solution possible :

plutôt fieldset / legend + aria-describedby pointant sur id du legend (pour assurer + de support du legend ) ???

      <label for="jourNaissance">Date de naissance</label>
      <input type="text" id="jourNaissance" aria-label="jour de naissance (JJ)">
      <input type="text" id="adresse" aria-label="mois de naissance (MM)">
      <input type="text" id="ville" aria-label="année de naissance (AAAA)">
  

Contrôle de saisie et message d'erreur

Lors de la validation, si des champs obligatoires ne sont pas renseignés, ou si le format de la donnée saisie n’est pas valide, il faut prévenir l’utilisateur.

Modifier le titre de page, le title

Le titre de la page doit refleter le contenu de celle-ci, donc, lorsqu'un formulaire génère des erreurs d'entrée, il faut l'annoncer à l'utilisateur via une modification du title. Il faut modifier dynamiquement le titre de page pour indiquer que le formulaire est en erreur et le nombre d'erreur commises (par exemple : "4 erreurs dans le formulaire d'inscription - Accueil Orange.com").

Utiliser l’attribut aria-invalid pour indiquer une erreur de saisie.

Indiquer dans le code les champs en erreur.


<input type="text" name="telephone" aria-invalid="true">

Annoncer dans une bannière que le formulaire est incomplet ou qu'il existe des erreurs

Pour remonter globalement les erreurs, l'impossibilité de valider un formulaire car des champs obligatoires ne sont pas remplis ou tout autre retour général d'erreur suite à l'entrée de données dans un formulaire, la solution à privilégier est un message d'alerte (dit aussi, selon les cas, de statut, d'état ou contextuel) constitué d'une bannière affichée en haut du formulaire, visible, répertoriant le nombre total d'erreurs à corriger, la liste de celle-ci, une identification précise du champ en erreur du type d'erreur (le nom est obligatoire, le numéro téléphone doit contenir 10 chiffres, par exemple) et si besoin des suggestions de corrections (une date valide : 11/02/2022, les numéros de série sont de la forme TS-XXX XXX, par exemple).

Pour ce message d'alerte, le focus doit être mis sur le titre du message (s'il existe, sinon, sur la première erreur de la liste), et chaque erreur doit avoir un lien vers le champ incriminé. De plus, pour que le contenu complet du message soit annoncé aux utilisateur d'AT sans prise de focus, on utilise le rôle ARIA alert. Ce type de message permet, même aux utilisateurs de technologies d'assistance (AT) d'être notifié du message lors de la non validation du formulaire.


      <div role="alert">
            <h2>Deux erreurs dans le formulaire</h2>
            <ul>
                  <li>
                        <a href="#nom" id="nom_error">
                              Le Nom de famille est un champ obligatoire, merci de le remplir.
                        </a>
                  </li>
                  <li>
                        <a href="#date" id="date_error">
                              Le champ Date de naissance doit respecter le format JJ/MM/AAAA, par exemple 13/07/2008.
                        </a>
                  </li>
            </ul>
          </div>

Avertir l’utilisateur au niveau du champ (en ligne) en cas d’erreur de saisie

Si des erreurs de saisie empêchent la validation du formulaire, plutôt que de lister les erreurs au début du formulaire dans une bannière (voir ci-dessus), on peut, pour chaque champ en erreur avertir l’utilisateur localement en ligne. Bien souvent des messages apparaissent à l’écran, cependant par défaut ils ne sont pas vocalisés au lecteur d’écran. Une des solutions consiste à déplacer automatiquement le focus dans le premier champ en erreur. Ceci aura pour effet de faire vocaliser le ou les libellés ou étiquettes du champ de saisie en question dans le ou lesquels le type erreur sera précisé (la date d'inscription est obligatoire, le numéro de sécurité sociale doit contenir 13 chiffres, par exemple) et si besoin des suggestions de corrections (un code valide : 1234-5678, le marquage produit est de la forme 1111-XXX-YYYY, par exemple).

Dans cet exemple de formulaire accessible, les messages d’erreurs sont déclarés comme des label et sont associés aux champs de saisie. Ainsi, lorsque le focus arrive dans un champ, le lecteur d’écran vocalise le libellé du champ puis le message d’erreur associé.


<label for="numero-serie">Veuillez saisir le numéro de série *</label>
<input aria-invalid="true" class="error" id="numero-serie" aria-describedby="helpblock" aria-required="true" type="text">
<label for="numero-serie" class="error" id="numero-serie-error">Le champ numéro de série est obligatoire.</label>

Attention, bien qu’il soit tout à fait HTML valide d’utiliser plusieurs label pour un même champ de formulaire, il est pour le moment conseillé de doubler avec un attribut aria-labelledby listant les id des deux (ou plus) label pour que le support soit assuré pour toutes les AT. Consulter l’article de Steve Faulkner pour plus d’information sur le sujet.


<label id="serie-label" for="numero-serie">Veuillez saisir le numéro de série *</label>
<input aria-invalid="true" class="error" aria-labelledby="serie-label serie-error" id="numero-serie" aria-describedby="helpblock" aria-required="true" type="text">
<label id="serie-error" for="numero-serie" class="error" id="numero-serie-error">Le champ numéro de série est obligatoire.</label>

Afficher des messages d’erreur explicites et, si besoin, suggérer des corrections

Les messages d’erreur affichés doivent être pertinents et, si besoin, proposer des exemples d’entrée valide dits aussi suggestions de correction.

Pour les messages d'erreur, quelques règles de bases :

Exemple valide :
capture d’écran d’un formulaire affichant des messages d’erreur valides

Exemple non-valide :
capture d’écran d’un formulaire affichant des messages d’erreur non-valides