La plupart du temps, lorsque que l’on souhaite gérer la validation du formulaire, on a recours au javascript pour gérer l’affichage des erreurs et avec éventuellement un style d’erreur sur les champs via des classes spécifiques.
Avec les récentes nouveautés CSS et HTML, il est possible de déléguer une certaine partie de ces erreurs au CSS.
Règles avec HTML
Rendre un champ obligatoire
Il suffit de mettre un attribut required pour que le navigateur sache que le formulaire ne doit pas être envoyé si le champ est vide.
Il applique alors un état invalide au champ ainsi qu’au formulaire.
Comme pour les champs obligatoires, les types permettent également d’effectuer des vérifications de format (Ex: email, tel, …).
On peut même appliquer des patterns avec des expressions régulières.
Nativement, les navigateurs affichent un message d’erreur dans une info-bulle lors de la soumission du formulaire, il est possible de compléter le message par exemple pour préciser le format attendu.
Pour cela, il faut utiliser l’attribut title :
<input type="text" pattern="[0-9]{3}-[0-9]{3}-[0-9]{4}" name="phone_number" required title="Le format attendu est 555-555-5555"/>
Soumission du formulaire
La soumission du formulaire sera automatiquement bloquée si un des champs n’est pas valide. Il n’est pas nécessaire de stopper son comportement via un écouteur d’évènement et un e.preventDefault().
Validation avec CSS
Maintenant que l’on a vu comment fixer les règles sur nos champs, voyons comment exploiter ces erreurs avec le CSS.
Gérer l'affichage avec les attributs
Plutôt que d’ajouter des classes en fonction des différents états de votre champ, je conseille plutôt de se baser sur les attributs HTML.
Par exemple, pour un champ désactivé, il est préférable de le cibler via l’attribut :
La pseudo-classe qui permet d’identifier si un champ est obligatoire est :required, Par exemple, on peut ajouter une étoile à côté du label si le champ est obligatoire.
Pour cela, on peut le combiner avec le :has()
La pseudo-classe qui permet d’identifier si un champ est valide est :user-valid, il suffit de lui appliquer un style de validation.
Il existe une autre pseudo-classe :valid, la différence entre les deux et que :user-valid ne réagit qu’après une interaction utilisateur.
La pseudo-classe qui permet d’identifier si un champ est invalide est :user-invalid, il suffit de lui appliquer un style d’erreur.
Il existe une autre pseudo-classe :invalid, la différence entre les deux et que :user-invalid ne réagit qu’après une interaction utilisateur.
La gestion de la tabulation est très importante lorsque l’on développe un formulaire notamment pour garantir une bonne accessibilité.
Gestion du focus
Lorsque l’on navigue avec la tabulation, il est primordial que l’utilisateur sache où il se trouve dans la page, sur quel élément il est positionné.
Pour l’ensemble des éléments focusables, la gestion du focus est gérée par les navigateurs avec une propriété de style outline que l’on pourra personnaliser.
La pire erreur en termes d’accessibilité serait de la supprimer.
:focus()
Pour appliquer cette modification, nous pouvons utiliser la pseudo-class :focus. On peut alors modifier le outline comme ceci :
Cela n’a pas grand intérêt d’indiquer le focus d’un bouton lorsque l’utilisateur clique dessus. Si on souhaite uniquement afficher le outline pour la tabulation, on peut plutôt utiliser le :focus-visible.
Si on souhaite détecter si un des champs est en état “focus” depuis un élément parent, nous pourrions utiliser le :has() :
fieldset:has(input:focus) {}
On peut faire la même chose avec la pseudo-classe :focus-within, elle est utile, lorsque l’on souhaite mettre en avant une sous-partie de formulaire et que l’utilisateur est “focus” sur un des champs.