Contrôle de la saisie

La mise en place d'un contrôle de ce qui est saisi dans un champs de formulaire favorise l'accessibilité du formulaire. Cela n'empêchera pas ensuite de vérifier que la saisie de l'utilisteur est conforme à l'attendu en effectuant ensuite des vérifications côté serveur.

Contrôle simple de la saisie des champs

Selon le type de champs déclaré, le navigateur effectuera un contrôle de la saisie et affichera une infobulle informative en cas d’erreur de saisie.

Champ obligatoire

Le champ obligatoire sera codé avec l’attribut required.

<form ...>
<p>Les champs signalés par une étoile(*) sont obligatoires.</p>
<label for="nom">Nom *</label>
<input type="text" name="nom" id="nom" required>
[...]
</form>

Champ d’adresse électronique

Le champ d’adresse électronique sera codé avec l’attribut type="email".
Par défaut, la saisie doit respecter la forme nom@domaine.ext.

Visuel
N.B. Pour les besoins de la démonstration, le champ a été rendu obligatoire.

Exemple email

Code HTML

<label for="mail">Votre adresse électronique <small>(de la forme nom@domaine.com)</small></label>
<input type="email" name="mail" id="mail" required>

Champ date

Le champ de type date sera codé avec l’attribut type="date".
La zone de saisie propose de manière native le format (jj/mm/aaaa) et utilise la calendrier cliquable natif du navigateur  plus besoin d’avoir recours à une librairie javascript comme c’était le cas en HTML 4.
Ces deux interactions natives font que ce champ est accessible.

Visuel
Renseigner une date ou cliquer sur l’icône en forme de calendrier. Pour les besoins de la démonstration, le champ a été rendu obligatoire.

Exemple de date

Code HTML

<label for="dateNaissance">Date de naissance *</label>
<input type="date" name="dateNaissance" id="dateNaissance" required>

Champ « fichier »

Le champ de type « fichier » sera codé avec l’attribut type="file".
Il permet de charger un fichier depuis son ordinateur.

Visuel

Exemple Chargement de fichier

Code HTML

<label for="fichier">Choisissez un fichier</label>
<input type="file" name="fichier" id="fichier">

Champ « mot de passe »

Le champ « mot de passe » sera codé avec l’attribut type="password".
Le texte saisi sera masqué par des ronds ou des étoiles selon le type de navigateur.

Visuel

Exemple Mot de passe

Code HTML

<label for="mdp">Votre mot de passe</label>
<input type="password" name="mdp" id="mdp" required>

Champ numérique

Le champ numérique sera codé avec l’attribut type="number".
La saisie est libre et des flèches haut et bas sont implémentées nativement pour sélectionner, par défaut, un nombre entier négatif ou positif.

Visuel

Exemple Nombre

Code HTML

<label for="ChiffrePorteBonheur">Votre chiffre porte-bonheur</label>
<input type="number" name="ChiffrePorteBonheur" id="ChiffrePorteBonheur">

Champ « numéro de téléphone »

Le champ « numéro de téléphone » sera codé avec l’attribut type="tel".
La saisie est libre ; par défaut, le champ affichera un clavier de saisie sur les supports numériques de type « mobile ».

Visuel

Exemple Numéro de téléphone

Code HTML

<label for="telephone">Votre numéro de téléphone</label>
<input type="tel" name="telephone" id="telephone">

Champ « URL »

Le champ « URL » sera codé avec l’attribut type="url".
La saisie est libre ; par défaut, la valeur saisie doit respecter la forme schema://restedelurl.

Visuel

Exemple Adresse site web

Code HTML

<label for="url">URL de votre site <small>(de la forme schema://restedelurl)</small></label>
<input type="url" name="url" id="url">

Contrôles supplémentaires sur la valeur saisie

Des attributs supplémentaires peuvent être ajoutés au champ input pour contrôler, côté utilisateur, la saisie du champs.

Taille minimum et maximum de la valeur saisie

  • Le nombre minimum de caractères que l’utilisateur peut saisir dans le champ sera codé avec l’attribut minlength. La valeur de minlength doit être un entier positif ou nul.
  • Le nombre maximum de caractères que l’utilisateur peut saisir dans le champ sera codé avec l’attribut maxlength. La valeur de maxlength doit être un entier positif ou nul et doit être supérieure à la valeur de minlength.

Le champ n’a pas besoin d’avoir l’attribut required pour que le contrôle s’effectue. En l’absence d’attribut required, le contrôle s’effectuera à partir du moment où l’utilisateur aura saisie quelque chose dans le champ.

Visuel

Exemple Saisie limitée

Code HTML

<label for="prenom">Votre prénom <small>(de 3 à 50 caractères)</small></label>
<input type="text" id="prenom" name="prenom" minlength="3" maxlength="50">

Valeur minimale, maximale et incrémentation d’un nombre

Pour un champ de type number, il est possible d’imposer aussi le pas d’incrémentation du chiffre saisi.

  • La valeur minimale du nombre saisi par l’utilisateur sera codé avec l’attribut min. La valeur de min doit être un entier positif ou nul.
  • La valeur maximale du nombre saisi par l’utilisateur sera codé avec l’attribut max. La valeur de max doit être un entier positif ou nul et doit être supérieure à la valeur de min.
  • Le pas d’incrémentation du nombre sera codé avec l’attribut step. Si on veut autoriser les valeurs décimales, elle sera spécifiée dans la valeur de l’attribut step. Ainsi :
    • Si on veut autoriser 2 chiffres après la virgule, on codera : step="0.01".
    • Si on veut autoriser uniquement les valeurs entières et les demis (xx,5), on codera : step="0.5".

Visuel
Cliquer les flèches haut et bas de la zone de saisie pour afficher les chiffres.

Exemple Incrémentation

Code HTML

<label for="nb1">Chiffre à 2 décimales <small>(de 0 à 10)</small></label>
<input type="number" id="nb1" name="nb1" min="0" max="10" step="0.01" >

<label for="nb2">Chiffre entier et demi <small>(de 1 à 10 : 1, 1.5, 2, ...)</small></label>
<input type="number" id="nb2" name="nb2" min="1" max="10" step="0.5">

Motif de saisie

Pour imposer un motif de saisie à respecter, on aura recours à l’attribut pattern. Cet attribut comportera une expression régulière (RegExp) à respecter.

Visuel
Pour les besoins de la démonstration, le champ « mot de passe » ne porte pas l’attribut type="password" mais type="text".

Mot de passe avec motif

Code HTML

<label for="mdpMotif">Votre mot de passe <small>(12 à 30 caractères contenant au moins une lettre majuscule, une lettre minuscule, un chiffre et un caractère spécial parmi @$!%?&)</small></label>
<input id="mdpMotif" name="mdpMotif" pattern="^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%?&amp;])[A-Za-z\d@$!%?&amp;]{12,30}$" type="password" title="Un mot de passe de 12 à 30 caractères contenant au moins une lettre majuscule, une lettre minuscule, un chiffre et un caractère spécial parmi @$!%?&">

astuce

Pour vous aider sur les expressions régulières, voici quelques ressources :

Formats de fichier acceptés

Pour imposer un format de fichier à charger, on aura recours à l’attribut accept.

Code HTML

<input
  type="file"
  id="docMicrosoft"
  accept=".doc,.docx,application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document" />

Gestion des erreurs

Titre de la page

En cas d’erreur, le titre de la page HTML sera modifiée en conséquence.

<head>
<title>Erreur - Formulaire d'envoi de votre commande</title>
...
</head>

Message d’erreur global

Un message d’erreur global peut être implémenté au début du formulaire  il aura alors le rôle role="alert".
Cette zone prévue pour recevoir le message d’alerte global sera implémentée à vide dans la formulaire puis peuplée au moment du retour d’erreur.

remarque

Il est fortement recommandé de positionner dès le chargement de la page l’attribut aria-live pour maximiser la compatibilité avec les différents couples navigateurs et lecteurs d’écran. Par conséquent ces zones seront prévues dès le chargement de la page et peuplées uniquement en cas d’erreur.

Exemple

Visuel

Erreur

Il y a 2 erreurs dans le formulaire.

Code HTML de l’exemple

<div role="alert" aria-live="assertive">
  <h2>Erreur</h2>
  <p>Il y a 2 erreurs dans le formulaire. Veuillez vérifier et réessayer.</p>
</div>

Code CSS de l’exemple

div[role="alert"] {
  padding: 1.25rem ;
  margin-top: 1.25rem;
  margin-bottom: 1.25rem;
  color: darkred;
  background-color: #FFD6D6;
  border-left: 0.75rem solid darkred;
}
div[role="alert"] h2  {
  font-weight: bold;
  font-variant: small-caps;
  font-size: 1.75rem;
  margin-bottom: 0;
}
div[role="alert"] p:last-of-type {
  margin-bottom: 0;
}
div[role="alert"]:empty {
  display: none;
}

Message d’erreur contextuel (associé au champ en erreur)

La gestion des erreurs doit suivre les règles suivantes :

  • Pour le champ en erreur :
    • Il est relié au message d’erreur grâce à l’attribut aria-describedby pour pouvoir être restitué par les logiciels de synthèse vocale 
    • Il (et/ou son label) n’est pas signalé uniquement par la couleur (le champ en erreur pourra alors avoir une bordure plus grosse par exemple et son libellé écrit en gras) ;
    • Il possède l’attribut aria-invalid="true"  ;
    • Le focus clavier est mis sur le premier champ en erreur afin de pouvoir parcourir tout le formulaire ;
  • Pour le message d’erreur :
  • Il est accolé au champ en erreur ;
  • Il explique les raisons de l’erreur de manière claire et sans ambiguïté ;
  • Il rappelle ce qui est attendu dans le champ et donne des suggestions de correction (exemple : Veuillez renseigner un email valide du type nom@domaine.fr) ;
  • Le message d’erreur pour un champ obligatoire est contextualisé et unique (exemple : Le champ “Nom” est obligatoire) ;
  • Il est inséré dans une zone (élément HTML div) portant l’attribut id le reliant au champ ;
  • Pour maximiser la compatibilité avec les logiciels de synthèse vocale (même si cette redondance occasionne un problème de double restitution orale dans VoiceOver sur iOS.), la zone du message d’erreur (élément HTML div) aura l’attribut aria-live="assertive".

Exemple de code HTML

<label for="email">Adresse e-mail</label>
<input type="email" id="email" name="email" autocomplete="email" required aria-invalid="true"  aria-describedby="erreurEmail" />
    <div id="erreurEmail" aria-live="assertive">
        <p id="emailObligatoire">Le champ email est obligatoire.</p>
        <p id="emailFormatage">Veuillez renseigner un email valide (prenom.nom@domaine.fr)</p>
    </div>

remarque

Il est fortement recommandé de positionner dès le chargement de la page l’attribut aria-live pour maximiser la compatibilité avec les différents couples navigateurs et lecteurs d’écran. Par conséquent ces zones seront prévues dès le chargement de la page et peuplées uniquement en cas d’erreur.

Exemple

Visuel

Veuillez renseigner un email valide (prenom.nom@domaine.fr)

Code HTML de l’exemple
Remarquez dans le code ci-dessous que l’élément input se trouve dans l’élément label.

<label for="email">Adresse e-mail
<input type="email" id="email" name="email" autocomplete="email" required aria-invalid="true"  aria-describedby="erreurEmail" />
</label>
<div id="erreurEmail" aria-live="assertive" class="erreurContexte"></div>

Code CSS de l’exemple

label {
  display: block;
}
label:has([aria-invalid="true"]) {
  color: darkred;
}
input {
  width: 300px;
  display: block;
  padding: 0.5em 0.75em;
}
input[aria-invalid="true"] {
  border: 3px solid darkred;
}
div[aria-live="assertive"]:empty {
  display: none;
}
.erreurContexte {
  color: darkred;
}
.erreurContexte p:first-child::before {
   --icon-size: 1rem;
  content: "";
  background-color: currentColor;
  display: inline-block;
  height: var(--icon-size);
  width: var(--icon-size);
  vertical-align: calc((.75em - var(--icon-size))*.5);
  margin-right: calc(var(--icon-size)*0.25);
  -webkit-mask-size: 100% 100%;
  mask-size: 100% 100%;
  -webkit-mask-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M256 32c14.2 0 27.3 7.5 34.5 19.8l216 368c7.3 12.4 7.3 27.7 .2 40.1S486.3 480 472 480L40 480c-14.3 0-27.6-7.7-34.7-20.1s-7-27.8 .2-40.1l216-368C228.7 39.5 241.8 32 256 32zm0 128c-13.3 0-24 10.7-24 24l0 112c0 13.3 10.7 24 24 24s24-10.7 24-24l0-112c0-13.3-10.7-24-24-24zm32 224a32 32 0 1 0 -64 0 32 32 0 1 0 64 0z"/></svg>');
  mask-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M256 32c14.2 0 27.3 7.5 34.5 19.8l216 368c7.3 12.4 7.3 27.7 .2 40.1S486.3 480 472 480L40 480c-14.3 0-27.6-7.7-34.7-20.1s-7-27.8 .2-40.1l216-368C228.7 39.5 241.8 32 256 32zm0 128c-13.3 0-24 10.7-24 24l0 112c0 13.3 10.7 24 24 24s24-10.7 24-24l0-112c0-13.3-10.7-24-24-24zm32 224a32 32 0 1 0 -64 0 32 32 0 1 0 64 0z"/></svg>');
}

Gestion du succès

À l’issue de la soumission du formulaire, si celle-ci s’est bien passée, il faut afficher un message de notification pour en informer l’utilisateur. Ce message peut reprendre une partie des données renseignées dans le formulaire.

  • Ce message de succès / confirmation s’implémente via le rôle aria role="status".
  • Pour maximiser la compatibilité avec les logiciels de synthèse vocale, ajouter un aria-live="polite" même s’il est redondant lorsque vous utiliserez ce rôle.
<div role="status" aria-live="polite">
<h2>Succès</h2>
<p>Votre demande a bien été envoyée ; vous recevrez bientôt un mail de confirmation à l'adresse suivante : martin@gmail.com.</p>
</div>

remarque

Il est fortement recommandé de positionner dès le chargement de la page l’attribut aria-live pour maximiser la compatibilité avec les différents couples navigateurs et lecteurs d’écran. Par conséquent ces zones seront prévues dès le chargement de la page et peuplées uniquement en cas de succès.

Exemple

Visuel

Succès

Votre message a bien été envoyé.

Code HTML de l’exemple

<div role="status" aria-live="polite">
  <h2>Succès</h2>
  <p>Votre message a bien été envoyé.</p>
</div>

Code CSS de l’exemple

div[role="status"] {
  padding: 1.25rem ;
  margin-top: 1.25rem;
  margin-bottom: 1.25rem;
  color: darkgreen;
  background-color: #d0f7d0;
  border-left: 0.75rem solid darkgreen;
}
div[role="status"] h2 {
  font-weight: bold;
  font-variant: small-caps;
  font-size: 1.75rem;
}
div[role="status"] p:last-of-type {
  margin-bottom: 0;
}