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.
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.
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
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
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
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
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
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 deminlength
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 demaxlength
doit être un entier positif ou nul et doit être supérieure à la valeur deminlength
.
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
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 demin
doit être un entier positif ou nul. - La valeur maximale du nombre saisi par l’utilisateur sera codé avec l’attribut
max
. La valeur demax
doit être un entier positif ou nul et doit être supérieure à la valeur demin
. - 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’attributstep
. 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"
.
- Si on veut autoriser 2 chiffres après la virgule, on codera :
Visuel
Cliquer les flèches haut et bas de la zone de saisie pour afficher les chiffres.
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"
.
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)(?=.*[@$!%?&])[A-Za-z\d@$!%?&]{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 :
- Exemples de la documentation MDN.
- regexr.com, site de documentation et de test des expressions régulières.
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 ;
- Il est relié au message d’erreur grâce à l’attribut
- 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’attributid
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’attributaria-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
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;
}