Formulaire partie 1 - Structurer son formulaire

Thématiques associées :
  • Web
  • Intermédiaire
  • Composant

Introduction #

Pour qu’un formulaire soit accessible à l’ensemble des utilisateurs, quelques règles doivent être respectées lors du développement.

Nous verrons, dans cette première partie, comment bien construire son formulaire, puis, dans une deuxième partie, la soumission d'un formulaire et les étapes de validation.

Nous allons développer un formulaire d'inscription afin de voir toutes les subtilités pour rendre un 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.

Étiqueter les champs de formulaires #

Les étiquettes doivent décrire le rôle de chaque champ du formulaire. Afin que tous les utilisateurs puissent avoir accès à la même information, il est important que ces étiquettes soient correctement associées à leurs champs de formulaire. Pour réaliser ceci il existe plusieurs techniques.

La balise label #

La solution privilégiée est l'utilisation de la balise label. C'est la mieux supportée par les technologies d'assistance. Il existe deux manières d'utiliser cette balise label :

  • lier explicitement la balise label avec son champ en renseignant un attribut for qui correspondra avec l'id du champ de formulaire auquel il est associé
  • lier implicitement la balise label avec son champ, dans ce cas, la balise label sera utilisée comme un conteneur entourant le champ de formulaire, La première solution est conseillée.

Exemple #

Exemple d'étiquettes correctement liées de manière explicite :

Exemple de code :

  
  <form id="formulaire" class="border border-secondary p-3 my-2">
    <div class="mb-2">
        <label for="email" class="form-label">Email</label>
        <input type="text" class="form-control" id="email"/>
    </div>
    <div class="mb-2">
      <label for="name" class="form-label">Nom</label>
      <input type="text" class="form-control" id="name"/>
    </div>
    <div class="mb-2">
      <label for="firstname" class="form-label">Prénom</label>
      <input type="text" class="form-control" id="firstname"/>
    </div>
  </form>
  

Masquer les étiquettes de manière accessible #

Dans certains cas, il peut être utile de masquer l'étiquette visuellement. Attention, on peut masquer les étiquettes si et seulement si la fonction champ est suffisamment claire et compréhensible dans son contexte: par exemple, un champ de recherche à côté d'une icone loupe.

Même si l'étiquette est masquée visuellement, elle doit toujours être accessible pour les technologies d'assistance.

Cette méthode consiste a utiliser une classe CSS (utilisation de la classe visually-hidden de Bootstrap/Boosted) permettant un masquage accessible. 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 l’exemple sur le masquage accessible pour plus l’information.

Exemple #

Par exemple, nous pouvons utiliser le masquage accessible pour un champ de recherche, si un bouton avec pour libellé recherche, ou une image loupe, est à coté du champ. Ainsi, l'étiquette du champ est cachée visuellement afin d'éviter une redondance.
Exemple de code :

  
    <label for="recherche" class="visually-hidden">Recherche: </label>
    <input type="text" name="recherche" id="recherche">
    <button type="submit">Recherche</button>
  

Les attributs ARIA #

Il est aussi possible d'utiliser les attributs aria-label et aria-labelledby pour étiqueter des champs de formulaire, car ces attributs sont bien supportés par les navigateurs et dans les AT récentes :

  • L’attribut aria-labelledby permet de préciser l’id d’un élément présent dans le code qui sera utilisé pour étiqueter le champ.
  • L’attribut aria-label permet de préciser directement un label sous forme d’une chaîne de caractères. Attention l'information ne sera pas donnée visuellement.

Un exemple possible :

  
    <input type="text" name="recherche" aria-labelledby="recherche">
    <button id="recherche" type="submit" class="icon-loup" aria-label="Recherche"></button>
  

L'attribut title #

L’attribut title permet 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 novices du numérique.

Attention, nous pourrions être tentés d'utiliser l'attribut placeholder. Cet attribut n'est pas assez robuste, en effet :

  • le texte du placeholder qui s’affiche dans le champ n’est généralement pas assez contrasté ;
  • il s’efface à la saisie du contenu dans le champ (entraînant des difficultés en cas de déficience cognitive) ;
  • le placeholder n’est pas toujours lu par les aides techniques ;
  • il rend les corrections difficiles en cas d’erreur s'il n'existe pas de label affiché ;

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.

Regrouper les champs de même nature #

Lorsque nécessaire, il est important de regrouper les champs de même nature, ça permettra de rendre l'ensemble du formulaire plus compréhensible.
La plupart du temps, on regroupe nos boutons radio, ou nos cases à cocher, afin d'associer une entête à ces éléments.

Pour les regrouper, on utilise la balise fieldset, qui aura comme premier enfant la balise legend qui servira d'entête à nos champs regroupés.

Exemple #

Dans notre formulaire d'inscription, on peut ajouter le genre de notre utilisateur. Pour cela, on va implémenter des boutons radio, et les regrouper avec l'entête Genre

[...]
Genre

Un exemple possible :

  
    <div class="col-md-8">
    <form id="formulaire3" class="border border-secondary p-3 my-2">
      [...]
      <fieldset>
        <legend>Genre</legend>
        <div class="form-check form-check-inline">
          <input class="form-check-input" type="radio" name="inlineRadioOptions" id="M" value="M">
          <label class="form-check-label" for="M">M</label>
        </div>
        <div class="form-check form-check-inline">
          <input class="form-check-input" type="radio" name="inlineRadioOptions" id="Mme" value="Mme">
          <label class="form-check-label" for="Mme">Mme</label>
        </div>
        <div class="form-check form-check-inline">
          <input class="form-check-input" type="radio" name="inlineRadioOptions" id="Non-binaire" value="Non-binaire" >
          <label class="form-check-label" for="Non-binaire">Non-binaire</label>
        </div>
      </fieldset>
    </form>
  </div>
  

Préciser le type ou le format attendu #

Pour aider l'utilisateur, il est aussi important de lui préciser le type ou le format attendu lorsque nécessaire. Par exemple, pour une date de naissance, on doit, si besoin, lui indiquer le format de saisie (jj/mm/aaaa).

Pour informer l'utilisateur, on peut :

  • fournir les instructions dans le label
  • utiliser l'attribut aria-labelledby ou aria-describedby

Exemple #

Pour notre formulaire d'inscription, nous allons rajouter un champ mot de passe en précisant le format que l'on souhaite.

Lorsqu'on ajoute un champ mot de passe, il est aussi important de laisser la possibilité d'afficher ou de cacher le mot de passe. Cela permet aux utilisateurs atteint de troubles moteurs, de l'attention ou cognitifs d'éviter d'éventuelles erreurs de saisie.

Votre mot de passe doit contenir minimum 6 caractères.

Un exemple possible :

  
  <div class="col-md-8">
    <form id="formulaire4" class="border border-secondary p-3 my-2">
      <label for="password" class="form-label">Mot de passe </label>
      <div class="mb-2 input-group">
        <input type="password" class="form-control" id="password" aria-describedby="passwordHelpBlock"/>
        <span class="input-group-text">
          <button type="button" class="btn btn-icon btn-secondary btn-sm" id="password_visibility" title="Afficher le mot de passe" >
            <svg aria-hidden="true" focusable="false" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
              [...]
            </svg>
          </button>
        </span>
      </div>
      <div id="passwordHelpBlock" class="form-text">
          Votre mot de passe doit contenir minimum 6 caractères.
        </div>
    </form>
  </div>
  

Exemple complet #

L'exemple complet avec tous les éléments que l'on a passés en revue. Dans la deuxième partie, on verra comment valider le formulaire et gérer les messages d'erreurs.
Pour la suite de l'exercice et compléter notre formulaire d'inscription, nous avons rajouté des champs pour l'adresse (adresse, ville, code postal).

Votre mot de passe doit contenir minimum 6 caractères.
Genre

Le code final :

  
  <div class="col-md-8">
    <form id="formulaire_final" class="border border-secondary p-3 my-2">
      <div class="mb-2">
        <label for="email_final" class="form-label">Email</label>
        <input type="text" class="form-control" id="email_final"/>
      </div>
      <label for="password_final" class="form-label">Mot de passe </label>
      <div class="mb-2 input-group">
        <input type="password" class="form-control" id="password_final" aria-describedby="passwordHelpBlock_final"/>
        <span class="input-group-text">
          <button type="button" class="btn btn-icon btn-secondary btn-sm" id="password_visibility_final" title="Afficher le mot de passe" >
            <svg aria-hidden="true" focusable="false" fill="currentColor" xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 1000 1000"></svg>
          </button>
        </span>
      </div>
      <div id="passwordHelpBlock_final" class="form-text">
          Votre mot de passe doit contenir minimum 6 caractères.
      </div>
      <div class="mb-2">
        <label for="name_final" class="form-label">Nom</label>
        <input type="text" class="form-control" id="name_final"/>
      </div>
      <div class="mb-2">
        <label for="firstname_final" class="form-label">Prénom</label>
        <input type="text" class="form-control" id="firstname_final"/>
      </div>
      <fieldset>
        <legend>Genre</legend>
        <div class="form-check form-check-inline">
          <input class="form-check-input" type="radio" name="inlineRadioOptions_final" id="M_final" value="M">
          <label class="form-check-label" for="M_final">M</label>
        </div>
        <div class="form-check form-check-inline">
          <input class="form-check-input" type="radio" name="inlineRadioOptions_final" id="Mme_final" value="Mme">
          <label class="form-check-label" for="Mme_final">Mme</label>
        </div>
        <div class="form-check form-check-inline">
          <input class="form-check-input" type="radio" name="inlineRadioOptions_final" id="Non-binaire_final" value="Non-binaire" >
          <label class="form-check-label" for="Non-binaire_final">Non-binaire</label>
        </div>
      </fieldset>
      <div class="mb-2">
        <label for="adresse_final" class="form-label">Adresse</label>
        <input type="text" class="form-control" id="adresse_final"/>
      </div>
      <div class="mb-2">
        <label for="adresse2_final" class="form-label">Complément d'adresse</label>
        <input type="text" class="form-control" id="adresse2_final"/>
      </div>
      <div class="mb-2">
        <label for="ville_final" class="form-label">Ville</label>
        <input type="text" class="form-control" id="ville_final"/>
      </div>
      <div class="mb-2">
        <label for="cp_final" class="form-label">Code postal</label>
        <input type="text" class="form-control" id="cp_final"/>
      </div>
    </form>
  </div>
  

Lien vers la deuxième partie #

Formulaire partie 2 - Soumettre son formulaire