Chaque champ de saisie — input, select, textarea — doit avoir une étiquette qui décrit ce qu'on attend de l'utilisateur. Cette étiquette doit être à la fois visible à l'écran et liée programmatiquement au champ. C'est le critère 11.1, et c'est sur le checkout e-commerce qu'il casse le plus.

Les deux manières correctes

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

<!-- ou bien, en imbriquant -->

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

Dans la première forme, l'attribut `for` du label pointe vers l'`id` du champ : c'est le lien programmatique. Dans la seconde, le champ est imbriqué dans le label, ce qui crée le lien implicitement. Les deux sont conformes ; la première est la plus robuste car indépendante de la mise en page.

Ce qui ne suffit PAS

  • `<input placeholder="Email">` seul — le placeholder disparaît à la saisie et n'est pas un label
  • Un texte à côté du champ sans `<label for>` — visuellement c'est un label, programmatiquement non
  • `aria-label="Email"` sur un champ visible — accessible au lecteur d'écran, mais sans label affiché pour les autres utilisateurs
  • Une astérisque rouge seule pour signaler "obligatoire" — la couleur ne porte pas l'information

Le piège n°1 : le placeholder en guise de label

C'est l'anti-pattern le plus répandu. Un champ avec seulement `placeholder="Nom"` paraît étiqueté tant qu'il est vide. Dès que l'utilisateur tape, le repère disparaît : impossible de vérifier qu'on remplit le bon champ, impossible de se relire. Pour les personnes âgées et les utilisateurs de lecteurs d'écran, le formulaire devient un labyrinthe. Le placeholder est un complément, jamais un substitut au label.

Cas particuliers e-commerce

Le champ de recherche

L'icône loupe ne fait pas office de label. Ajoutez un `<label>` visuellement masqué (classe `sr-only` / `screen-reader-text`) ou, à défaut, un `aria-label="Rechercher un produit"` sur le champ.

Les cases CGV et newsletter

La case d'acceptation des conditions générales doit avoir un label cliquable décrivant l'engagement. Un simple "J'accepte" posé à côté d'une case non liée est un échec 11.1 fréquent en fin de tunnel.

Pièges PrestaShop / WooCommerce

Les modules de paiement tiers (Stripe Elements, PayPal Smart Buttons) injectent leurs propres champs, souvent dans une iframe. Beaucoup n'ont pas de label correct, et vous ne pouvez pas toujours les corriger côté thème. Vérifiez après chaque mise à jour de module, et signalez le défaut à l'éditeur si besoin.

Comment le détecter

Un moteur comme axe-core repère les champs sans nom accessible instantanément. Sur le checkout, c'est le critère qui bloque le plus de tunnels d'achat pour les utilisateurs aveugles — donc celui dont le préjudice est le plus direct, et l'argumentation juridique la plus forte en cas de plainte. Un audit ComplAudit liste chaque champ sans label avec son sélecteur DOM et le fichier template concerné.

Questions fréquentes

aria-label ou <label> visible : que choisir ?

Toujours `<label>` visible quand c'est possible. `aria-label` ne rend le champ accessible qu'aux lecteurs d'écran ; il laisse sans repère les utilisateurs voyants qui ont besoin d'un label affiché. Réservez `aria-label` aux cas où un label visible est réellement impossible.

Un placeholder est-il interdit ?

Non. Le placeholder reste utile pour montrer un format attendu ("jj/mm/aaaa"). Il devient un problème uniquement quand il remplace le label au lieu de le compléter.

Faut-il un label sur les champs en lecture seule ?

Oui pour les champs en lecture seule visibles : l'utilisateur doit savoir ce qu'ils contiennent. Les champs réellement cachés (`type="hidden"`) ne sont pas concernés.

Repérer chaque champ sans label sur votre checkout, avec son emplacement exact :

→ Lancer un audit