Guides Formulaires

Comment créer un formulaire accessible : labels, erreurs, focus et CAPTCHA

Les formulaires : le point critique de l'accessibilité

Si je devais choisir un seul sujet sur lequel former les équipes, ce serait les formulaires. Ce sont le principal moyen d'interaction sur un site — inscription, contact, achat, connexion — et pourtant ce sont les composants les plus souvent inaccessibles. Le thème 11 du RGAA y consacre 13 critères. Il y a une raison à ça.

Labels : la base de tout

Chaque champ doit avoir un label visible et correctement associé. C'est tout bête, mais c'est la base :

<label for="email">Adresse email</label> <input type="email" id="email" name="email">

Trois règles à graver dans le marbre :

  • Le for correspond à l'id de l'input — c'est ce lien qui permet au lecteur d'écran d'annoncer le label
  • Le label doit être visible à l'écran, pas juste dans le code
  • Le placeholder n'est PAS un label. Je le répète à chaque formation : il disparaît dès qu'on commence à taper, et il a souvent un contraste insuffisant. C'est le piège classique dans lequel tombent 90 % des designers

Groupement fieldset/legend

Quand vous avez des champs liés entre eux (une adresse, un groupe de boutons radio), regroupez-les :

<fieldset> <legend>Adresse de livraison</legend> <label for="rue">Rue</label><input id="rue"> <label for="ville">Ville</label><input id="ville"> </fieldset>

Champs obligatoires

Ne vous contentez pas d'une petite astérisque rouge toute seule :

  • Ajoutez required ou aria-required="true" dans le code
  • Indiquez visuellement avec une astérisque ET une mention globale en haut du formulaire (« Les champs marqués d'un * sont obligatoires »)
  • L'astérisque seule ne suffit pas — tout le monde ne sait pas ce qu'elle signifie

Messages d'erreur accessibles

C'est là que beaucoup de formulaires échouent. Un message d'erreur qui dit juste « Erreur » en rouge, ça n'aide personne. Voici comment faire correctement :

<label for="tel">Téléphone</label> <input id="tel" aria-describedby="tel-error" aria-invalid="true"> <p id="tel-error" class="error">Format attendu : 06 12 34 56 78</p>
  • Le message est associé au champ via aria-describedby — le lecteur d'écran l'annonce automatiquement
  • Le champ porte aria-invalid="true" pour signaler l'état d'erreur
  • Un résumé des erreurs en haut du formulaire avec des liens vers les champs concernés
  • Le focus se déplace automatiquement vers le résumé après soumission

Gestion du focus

Le focus, c'est ce qui guide l'utilisateur clavier dans votre formulaire :

  • Ordre de tabulation logique — pas de tabindex > 0, ça casse tout
  • Focus visible sur tous les champs et boutons, sans exception
  • Après une erreur : le focus va vers le résumé ou vers le premier champ en erreur
  • Après un succès : annonce claire et focus vers le message de confirmation

Types et autocomplete

Deux petites optimisations qui changent la vie des utilisateurs :

  • Utilisez les bons types HTML5 : type="email", type="tel", type="url" — le clavier mobile s'adapte
  • Ajoutez les attributs autocomplete : autocomplete="email", autocomplete="given-name" — le navigateur pré-remplit intelligemment

CAPTCHA accessible

Les CAPTCHA visuels classiques sont un cauchemar pour l'accessibilité. Voici les alternatives qui marchent :

  • reCAPTCHA v3 : invisible, basé sur le comportement — l'utilisateur ne voit rien
  • Honeypot : un champ caché piège pour les bots, invisible pour tous les humains
  • Turnstile (Cloudflare) : sans défi visuel, très fluide
  • hCaptcha avec option audio pour les utilisateurs malvoyants
Un formulaire inaccessible, c'est une porte fermée. Vos utilisateurs ne vont pas se battre pour la forcer — ils iront simplement ailleurs.
Non, jamais. Je le redis parce que c'est l'erreur la plus courante : le placeholder disparaît dès qu'on commence à taper, il a souvent un contraste insuffisant, et les lecteurs d'écran ne le traitent pas comme un vrai label. Utilisez toujours un label visible et correctement associé. Le placeholder peut servir d'exemple de format (« ex : 06 12 34 56 78 »), mais c'est tout.
Oubliez les CAPTCHA visuels classiques — ils sont un cauchemar pour l'accessibilité. Préférez reCAPTCHA v3 qui est invisible et basé sur le comportement, ou Cloudflare Turnstile qui ne pose aucun défi visuel. La technique du honeypot est aussi très efficace : un champ caché que seuls les bots remplissent, totalement invisible pour les humains.
Concrètement : un résumé des erreurs en haut du formulaire avec des liens cliquables vers chaque champ en erreur. Chaque message d'erreur est relié à son champ via aria-describedby. Les champs en erreur portent aria-invalid="true". Et après soumission, le focus se déplace automatiquement vers le résumé. C'est cette combinaison qui fait la différence.

Testez la conformité de votre site

Scannez votre site et obtenez un rapport détaillé avec recommandations IA.

Scanner mon site - 15€