Normes · WCAG 2.2

SC 4.1.2 Niveau A WCAG 2.0

Nom, rôle, valeur

Chaque composant d'interface doit exposer programmatiquement un nom, un rôle et — le cas échéant — une valeur et un état. Sans cela, les lecteurs d'écran, la commande vocale et les dispositifs à contacteur ne peuvent ni identifier ni actionner le contrôle.

Ce que ce critère demande

Chaque élément interactif de la page — boutons, liens, champs de formulaire, onglets, curseurs, widgets personnalisés — doit exposer trois informations aux technologies d’assistance :

  • Nom — comment ce contrôle s’appelle-t-il ? (« Envoyer », « Fermer la boîte de dialogue », « Volume »)
  • Rôle — de quel type de contrôle s’agit-il ? (bouton, lien, case à cocher, onglet, curseur)
  • Valeur / état — pour les composants qui en ont un : est-il activé, développé, coché, sélectionné ? Quelle est la valeur actuelle ?

Cette exposition doit être programmatique — définie dans le DOM, non peinte par CSS. Les lecteurs d’écran, les plages braille, les logiciels de commande vocale et les scanners à contacteur lisent tous l’arbre d’accessibilité, pas les pixels.

Comment le satisfaire

  • Utiliser l’élément HTML natif chaque fois qu’il en existe un. <button> est livré avec le rôle correct, le focus, la gestion du clavier et un nom accessible tiré de son contenu textuel — gratuitement.
  • Pour les boutons avec icône seule, ajouter un aria-label (ou du texte masqué visuellement). <button aria-label="Fermer">×</button>.
  • Pour les champs de formulaire, associer un <label for> avec l’id du champ. Ou envelopper le champ à l’intérieur du <label>. Le texte de l’attribut placeholder n’est pas un label.
  • Lorsqu’un widget personnalisé doit être construit avec <div> et <span>, ajouter role="…", gérer tabindex, gérer les touches Entrée et Espace, et refléter l’état avec aria-pressed, aria-expanded, aria-checked, aria-selected, aria-valuenow.
  • Passer la page rendue dans l’inspecteur d’arbre d’accessibilité du navigateur (Chrome DevTools → Éléments → Accessibilité) et lire chaque contrôle : chacun doit être annoncé sous la forme nom + rôle + état.

Échecs courants

  • <div onclick="…"> mis en forme comme un bouton — pas de rôle, pas de clavier, pas de nom. Les lecteurs d’écran l’ignorent. La commande vocale ne peut pas dire « cliquer sur Enregistrer ».
  • <div role="button"> sans tabindex="0", sans gestionnaire Entrée/Espace — semble accessible, ne l’est pas.
  • Les boutons avec icône seule (<button><svg /></button>) sans aria-label, aria-labelledby ni texte masqué visuellement. Annoncés comme simple « bouton ».
  • Les listes déroulantes personnalisées construites avec <div> et JavaScript, manquant de role="combobox", aria-expanded, aria-controls et les rôles listbox/option sous-jacents.
  • Les boutons bascule (muet, favori, suivre) qui changent d’état visuellement mais ne mettent jamais à jour aria-pressed. Les utilisateurs voyants voient le changement ; les utilisateurs de lecteurs d’écran n’entendent aucune différence.
  • Les champs de formulaire avec un label visuel adjacent mais sans lien for/id ou <label> englobant.
  • Les cases à cocher personnalisées dessinées avec <svg> et un champ natif masqué qui ne reflète jamais :checked dans l’interface visible — les états du lecteur d’écran et visuels divergent.

Pourquoi c’est important

Il s’agit du critère le plus cité dans la spécification. Presque chaque plainte du type « ce site est inutilisable avec un lecteur d’écran » se résout en un échec 4.1.2 quelque part — généralement un <div> qui se fait passer pour un bouton, ou un bouton avec icône sans nom. C’est aussi là qu’apparaît le coût de la construction de widgets personnalisés : chaque contrôle HTML natif satisfait déjà 4.1.2 ; chaque widget <div> fait maison doit le mériter ligne par ligne. L’audit 4.1.2 le plus rapide consiste à naviguer au clavier sur la page avec un lecteur d’écran et écouter — tout ce qui s’annonce comme « vide » ou simplement « bouton » est un problème à corriger.