accessibility

Étiquetez chaque champ de formulaire

MetricSpot vérifie que chaque champ de formulaire a un <label>, un aria-label ou un aria-labelledby associé. Les champs non étiquetés sont annoncés comme « edit text » par les lecteurs d'écran.

Ce que vérifie ce contrôle

Parcourt chaque <input>, <textarea> et <select> de la page et vérifie que chacun a un nom accessible provenant de l’un de :

  • Un <label for="id"> explicite
  • Un <label> englobant <label>…<input>…</label>
  • Un attribut aria-label="…"
  • Un aria-labelledby="other-id" pointant vers du texte visible
  • Un attribut title (le pire — un tooltip au survol est un repli médiocre, mais ça compte)

Le contrôle échoue lorsqu’un champ n’a aucun de ces éléments et n’est pas un champ caché, un bouton de soumission ou un jeton csrf.

Pourquoi c’est important

Un utilisateur de lecteur d’écran remplissant un formulaire de paiement entend « edit text, edit text, edit text » au lieu de « numéro de carte, expiration, CVV ». Les champs non étiquetés sont inutilisables.

  • Impact sur la conversion, pas seulement la conformité. Toutes les études UX sur les formulaires de paiement montrent la même chose : les étiquettes visibles (et non placeholder seul) augmentent les taux de complétion de 10 à 20 %. Les placeholders disparaissent dès qu’on tape — votre utilisateur ne peut pas vérifier ce qu’il saisit.
  • Exposition juridique. Les étiquettes de formulaire font partie des échecs WCAG les plus souvent cités dans les procès d’accessibilité car elles sont faciles à vérifier (ouvrez la page dans NVDA, parcourez avec Tab). La plupart des plaintes ADA Title III déposées contre les sites e-commerce américains citent les étiquettes de formulaire parmi les trois principales violations.
  • L’autofill marche mieux. Les navigateurs et gestionnaires de mots de passe utilisent le texte de l’étiquette pour détecter le type de champ. Un champ « Email » étiqueté reçoit l’email en autofill ; un <input type="text"> non étiqueté non.

Comment le corriger

Utilisez un <label> visible relié au champ par for/id. Ne vous fiez pas au seul texte du placeholder.

Le pattern canonique :

<label for="email">Adresse e-mail</label>
<input id="email" name="email" type="email" autocomplete="email" required>

Pattern englobant (label comme parent, pas besoin de for) :

<label>
  Adresse e-mail
  <input name="email" type="email" autocomplete="email" required>
</label>

Boutons à icône seule (pas de texte visible) — utilisez aria-label :

<button type="submit" aria-label="Rechercher">
  <svg aria-hidden="true">…</svg>
</button>

React avec champs contrôlés :

<label htmlFor="email">Adresse e-mail</label>
<input
  id="email"
  type="email"
  value={email}
  onChange={(e) => setEmail(e.target.value)}
  autoComplete="email"
  required
/>

(Remarque : JSX utilise htmlFor, pas forfor est un mot réservé.)

Floating labels (Material Design, shadcn/ui) — l’étiquette visible est animée, mais le HTML sous-jacent doit toujours associer <label for> à <input id>. Si votre design system masque l’étiquette visuellement, utilisez class="sr-only" (un utilitaire Tailwind) au lieu de supprimer l’élément :

<label for="search" class="sr-only">Rechercher dans la doc</label>
<input id="search" type="search" placeholder="Rechercher…">

À ne pas faire.

  • N’utilisez pas le placeholder comme seule étiquette — il disparaît dès qu’on tape et a un contraste plus faible.
  • N’utilisez pas <div> ou <span> comme étiquette — ils n’exposent pas l’association aux technologies d’assistance.
  • Ne réutilisez pas le même id sur plusieurs champs — l’association se casse silencieusement.

Linters et CI. eslint-plugin-jsx-a11y fournit une règle label-has-associated-control. Ajoutez-la à votre config et faites échouer la CI sur les étiquettes manquantes. axe-core / Playwright peuvent les détecter au runtime — voyez l’extrait sur la page Score accessibilité Lighthouse.

Questions fréquentes

Le placeholder est-il une étiquette ?

Non. Les placeholders sont des indices pour les champs vides ; ils disparaissent au focus. WCAG indique explicitement que les placeholders ne satisfont pas l’exigence d’étiquetage.

Et aria-label ?

aria-label fonctionne, mais les étiquettes visibles fonctionnent mieux — les utilisateurs voyants avec des troubles cognitifs, les utilisateurs malvoyants avec loupe d’écran et les utilisateurs traduisant la page dans leur navigateur bénéficient tous d’un texte qu’ils peuvent voir. N’utilisez aria-label que lorsqu’une étiquette visible serait redondante (boutons à icône seule, champs de recherche avec une icône d’envoi claire).

Faut-il une étiquette pour les boutons de soumission ?

<button type="submit">S'inscrire</button> a son propre texte visible — c’est le nom accessible, pas besoin d’étiquette supplémentaire. Pareil pour <input type="submit" value="S'inscrire">. Les boutons de soumission à icône seule ont besoin d’aria-label.

Sources

Dernière mise à jour 2026-05-11