Skip to Content

Chapitre 9.1 — Les labels

⏱️ TL;DR — Le <label> est le pilier du formulaire accessible. Chaque champ (<input>, <select>, <textarea>) doit avoir un label qui lui est programmatiquement associé : soit un <label for="…"> lié à l’id du champ, soit un <label> qui englobe le champ. Sans lui, le lecteur d’écran annonce « zone de saisie » sans dire quoi saisir. Le placeholder n’est pas un label : il disparaît à la frappe, contraste souvent trop faible, et n’est pas restitué de façon fiable. On garde aria-label/aria-labelledby pour les rares cas sans texte visible possible.

🎯 Objectifs

  • Associer un <label> à chaque champ, par for/id ou par englobement.
  • Comprendre pourquoi le placeholder ne remplace jamais un label.
  • Savoir quand (et seulement quand) utiliser aria-label ou aria-labelledby.
  • Préférer les labels visibles aux labels cachés.

Pourquoi un label, concrètement

Quand un utilisateur de lecteur d’écran tabule jusqu’à un champ, l’outil annonce son nom accessible : « Adresse e-mail, zone de saisie ». Ce nom vient du label associé. Sans association, il entend juste « zone de saisie, vide » — il sait qu’il y a un champ, mais pas ce qu’il attend. Le formulaire devient une suite de boîtes muettes.

Le label sert aussi tout le monde : cliquer (ou toucher) le texte du label place le focus dans le champ et agrandit la cible — un vrai confort au clavier, à la souris et au tactile, particulièrement utile pour les petites cases à cocher.

📚 Aller plus loin — C’est le critère WCAG 3.3.2 Étiquettes ou instructions (niveau A) : quand un contenu requiert une saisie, des étiquettes ou instructions sont fournies. Voir aussi 4.1.2 Nom, rôle et valeur : le champ doit exposer un nom accessible aux technologies d’assistance.

Les deux bonnes façons d’associer un label

1. for + id (la plus courante)

L’attribut for du <label> pointe vers l’id du champ. C’est explicite et robuste, même si le label et le champ sont séparés dans le DOM.

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

2. Le label englobant

Le <label> entoure à la fois le texte et le champ. Pas besoin de for/id, mais garde-les si tu veux cibler le champ ailleurs (CSS, tests).

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

Les deux sont valides. Choisis-en une par projet et sois cohérent. Le point non négociable : un champ = un label associé.

Le placeholder n’est PAS un label

C’est l’erreur la plus répandue. Le design « épuré » sans labels, avec juste un texte gris dans le champ, casse l’accessibilité pour plusieurs raisons :

  • Il disparaît dès que l’utilisateur commence à taper : plus aucun rappel de ce qu’attend le champ.
  • Son contraste est presque toujours trop faible (gris clair sur blanc) — illisible pour beaucoup.
  • Il n’est pas restitué comme un label de façon fiable par les technologies d’assistance : certains lecteurs d’écran l’ignorent, d’autres le lisent en plus mais il ne remplace pas le nom accessible.
  • Il gêne la relecture : impossible de vérifier un champ rempli si l’indice a disparu.
<!-- ❌ Le placeholder fait office de label : nom accessible fragile, indice qui disparaît --> <input type="email" name="email" placeholder="Adresse e-mail" /> <!-- ✅ Label visible et associé ; le placeholder, s'il existe, n'est qu'un exemple secondaire --> <label for="email">Adresse e-mail</label> <input type="email" id="email" name="email" placeholder="ex. : prenom@exemple.fr" />

Le placeholder peut rester en complément, pour montrer un format d’exemple — jamais comme seule source du nom du champ.

⚠️ Piège — Utiliser le placeholder comme seul label. Visuellement ça « marche » tant que le champ est vide, mais tu perds l’indice à la frappe, tu descends sous le seuil de contraste, et tu prives l’utilisateur de lecteur d’écran d’un nom fiable. Si tu tiens au look minimaliste, garde un label visible et anime-le (motif « label flottant » bien implémenté, avec un vrai <label> associé) plutôt que de le supprimer.

aria-label et aria-labelledby : en dernier recours

Parfois, aucun texte visible n’est possible par choix de design — typiquement un champ de recherche avec juste une loupe. Là, tu donnes un nom accessible via ARIA :

<!-- Champ de recherche sans label visible : aria-label fournit le nom accessible --> <input type="search" name="q" aria-label="Rechercher un cours" /> <!-- Ou aria-labelledby si un texte visible existe déjà ailleurs --> <span id="titre-recherche">Rechercher</span> <input type="search" name="q" aria-labelledby="titre-recherche" />

Deux règles :

  1. Un label visible reste préférable. Il aide tout le monde, pas seulement les utilisateurs de lecteur d’écran : personnes avec troubles cognitifs, saisie vocale, ou simplement quelqu’un qui doute de ce qu’attend le champ.
  2. Si le champ a un texte visible à proximité, préfère aria-labelledby (qui pointe vers ce texte) ou un vrai <label> plutôt qu’un aria-label qui duplique — deux sources de nom qui divergent, c’est le début des bugs.

💡 Réflexe — Avant d’écrire aria-label, demande-toi : « puis-je afficher un vrai <label> ? ». Dans 9 cas sur 10, oui. ARIA remplace un nom manquant ; il ne doit pas devenir ton réflexe par défaut. Rappelle-toi la première règle d’ARIA : ne pas utiliser ARIA quand du HTML natif fait le travail.

🧭 Sur A11yLearn — Le formulaire d’inscription d’A11yLearn était le cas d’école du « design épuré » : trois champs (nom, e-mail, mot de passe) avec pour seuls repères des placeholders gris. À la tabulation, NVDA annonçait trois fois « zone de saisie, vide » — impossible de savoir quel champ était lequel. On a ajouté un <label> visible et associé à chaque champ. Résultat immédiat : « Nom complet, zone de saisie », « Adresse e-mail, zone de saisie », « Mot de passe, zone de saisie ». Le même formulaire, enfin utilisable à l’oreille.

✏️ Exercices

Exercice 1 — Corrige ce champ. Ce code s’appuie uniquement sur le placeholder. Rends-le accessible sans changer l’aspect fonctionnel.

<input type="text" name="fullname" placeholder="Nom complet" />

✅ Solution

Ajoute un <label> visible et associé. Tu peux garder le placeholder, mais comme exemple secondaire, pas comme nom du champ.

<label for="fullname">Nom complet</label> <input type="text" id="fullname" name="fullname" placeholder="ex. : Camille Martin" />

Le lecteur d’écran annonce maintenant « Nom complet, zone de saisie », et l’indice ne disparaît plus puisque le label reste affiché.

Exercice 2 — Un cas légitime d’ARIA ? Une barre de recherche dans l’en-tête n’a, par choix graphique, qu’une icône loupe et aucun texte. Quelle est la bonne approche, et pourquoi n’est-ce pas la solution idéale ?

✅ Solution

C’est un cas légitime de nom accessible via ARIA, car aucun texte visible n’est prévu :

<input type="search" name="q" aria-label="Rechercher un cours" />

Ce n’est pas idéal parce qu’un label visible aiderait aussi les personnes avec troubles cognitifs, la saisie vocale et tous ceux qui hésitent sur l’usage du champ. Si le design le permet, un vrai <label> (même visuellement discret mais lisible) reste supérieur à un aria-label qui n’existe que pour les technologies d’assistance.

🧠 Quiz de révision

1. Quelles sont les deux façons correctes d’associer un label à un champ ?

Le <label for="…"> dont le for pointe vers l’id du champ, ou le <label> qui englobe le champ. Les deux produisent un nom accessible fiable ; il faut juste être cohérent dans le projet.

2. Pourquoi le placeholder ne peut-il pas servir de label ?

Parce qu’il disparaît à la frappe, a un contraste presque toujours trop faible, et n’est pas restitué comme un nom accessible fiable par les technologies d’assistance. Il empêche aussi la relecture du champ rempli. Il peut rester comme exemple de format, en complément d’un vrai label.

3. Quel critère WCAG impose des étiquettes ou instructions pour les champs ?

Le critère 3.3.2 Étiquettes ou instructions (niveau A). Il se complète du 4.1.2 Nom, rôle et valeur, qui exige que le champ expose un nom accessible aux technologies d’assistance.

4. Quand aria-label est-il justifié, et que faut-il lui préférer si possible ?

Quand aucun texte visible n’est prévu par le design (ex. champ de recherche avec une simple loupe). On lui préfère toujours, si possible, un label visible (via <label>), qui bénéficie à tous et pas seulement aux utilisateurs de lecteur d’écran. Si un texte visible existe déjà, préfère aria-labelledby.

5. Quel bénéfice « bonus », au-delà du lecteur d’écran, apporte un label bien associé ?

Cliquer ou toucher le texte du label place le focus dans le champ (ou coche la case) et agrandit la cible — un gain de confort pour la souris, le clavier et le tactile, précieux pour les petites cases et boutons radio.


Chapitre suivant : Groupes & structure — grouper les champs liés et signaler les champs requis correctement.

Last updated on