Sélecteur de variantes produit (couleur, taille) accessible
En bref
- Le sélecteur de variantes (couleur, taille, matière) est le contrôle le plus manipulé d'une fiche produit — s'il est inaccessible, l'achat est bloqué net.
- Chaque option doit être atteignable et activable au clavier (Tab, flèches, Entrée/Espace) — WCAG 2.1.1.
- Une variante ne peut pas être identifiée par la couleur ou la forme seule : la pastille « rouge » doit porter le mot « Rouge » accessible — 1.4.1 · 1.1.1.
- L'option sélectionnée doit se voir autrement que par la couleur, avec un indicateur d'au moins 3:1 de contraste — 1.4.11 · 1.4.1.
- Une variante épuisée doit être signalée par du texte/un état (« épuisé »), pas seulement grisée — 1.4.1 · 4.1.2.
- Quand le choix change le prix, l'image ou le stock, le changement doit être annoncé au lecteur d'écran via
aria-live— 4.1.3.
Pourquoi le sélecteur de variantes est un point critique
Sur une fiche produit, choisir la couleur et la taille n'est pas une option : c'est l'étape obligatoire avant « Ajouter au panier ». Si ce contrôle n'est pas utilisable au clavier ou au lecteur d'écran, l'utilisateur ne peut tout simplement pas acheter.
C'est aussi l'un des composants les plus souvent recodés à la main par les thèmes et les plugins : des pastilles de couleur en <div> ou en <span>, des « boutons » de taille qui ne sont que des liens vides, des sélecteurs qui changent le prix sans rien annoncer. Chacun de ces raccourcis casse un critère WCAG précis.
La bonne nouvelle : un sélecteur de variantes accessible repose sur des patterns bien connus (groupe de boutons radio, ou liste déroulante native) et n'oblige presque jamais à renoncer au design des pastilles. Voici les six règles qui couvrent la quasi-totalité des cas.
Les 6 règles à appliquer
Grouper et nommer chaque jeu d'options
Chaque famille de variantes (Couleur, Taille, Matière) doit former un groupe nommé, pour que le lecteur d'écran annonce « Couleur : Rouge, sélectionné » et non juste « Rouge ». En pratique : un <fieldset> avec une <legend> « Couleur », ou un conteneur role="radiogroup" avec un aria-label="Couleur" / aria-labelledby pointant vers son intitulé.
L'intitulé visible (« Couleur : Rouge ») sert à la fois de label (3.3.2) et de retour sur le choix courant — gardez-le lié au groupe, pas posé à côté sans relation programmatique.
<fieldset><legend>Taille</legend>…
✓ role="radiogroup" aria-label="Couleur"
✗ Une rangée de pastilles sans intitulé de groupe
✗ « Couleur » en simple texte sans lien avec les options
De vrais contrôles, opérables au clavier
Deux patterns valides selon le design : soit une liste déroulante native (<select> avec ses <option>), accessible « gratuitement » ; soit un groupe de boutons radio (vrais <input type="radio"> stylés, ou boutons en role="radio" dans un role="radiogroup"). Les pastilles de couleur peuvent masquer visuellement un <input type="radio"> et garder toute l'accessibilité native.
Au clavier, le groupe radio se parcourt aux flèches et se sélectionne avec Espace ; un <select> s'ouvre et se choisit aux flèches + Entrée. À fuir : la pastille en <div onclick> ou <span>, sans rôle, sans focus, invisible pour le clavier et le lecteur d'écran (4.1.2).
<input type="radio" name="taille"> stylé en pastille
✓ <select> natif pour les longues listes
✓ Parcours aux flèches, sélection à l'Espace
✗ <div class="swatch" onclick> sans rôle ni focus
Jamais une option codée par la couleur (ou la forme) seule
Une pastille de couleur sans nom est muette pour qui ne distingue pas les couleurs ou navigue au lecteur d'écran : « bouton, bouton, bouton ». Le nom de la variante (« Rouge », « Bleu nuit », « Camel ») doit être disponible en texte — comme libellé visible, ou au minimum comme nom accessible (aria-label, texte en .sr-only, ou title + aria-label). C'est l'application directe de 1.4.1 (ne pas véhiculer l'information par la seule couleur) et de 1.1.1 (équivalent textuel d'un élément non-texte).
Même logique pour la taille si elle n'est signalée que par la dimension d'un cercle, ou pour une matière indiquée par un seul motif : ajoutez le libellé textuel.
Option sélectionnée : visible au-delà de la couleur, et contrastée
L'utilisateur doit voir laquelle des options est active. Si le seul signe est « la pastille devient un peu plus foncée », c'est insuffisant : ajoutez un repère non chromatique (anneau, coche, bordure épaisse, libellé « sélectionné »). Cet indicateur d'état est un élément non-texte porteur d'information : il doit atteindre un contraste d'au moins 3:1 avec ce qui l'entoure (1.4.11).
Pensez aussi au focus visible (2.4.7) : quand on parcourt les options au clavier, l'option ciblée doit avoir un contour net, distinct de l'état « sélectionné », pour qu'on sache toujours où l'on est.
aria-checked / aria-selected
✗ Sélection signalée par une nuance de couleur seule
✗ Bordure de sélection trop pâle (< 3:1)
Variantes indisponibles signalées autrement que « grisées »
Une taille épuisée souvent simplement « grisée » pose deux problèmes : le gris seul (information par la couleur, 1.4.1) et un contraste trop faible la rendent indétectable pour beaucoup d'utilisateurs. Indiquez l'indisponibilité par un texte (« épuisé », « bientôt de retour ») et exposez l'état programmatiquement : aria-disabled="true" sur le contrôle, ou <option disabled> dans un <select> (4.1.2).
Conseil pratique : préférez aria-disabled à un retrait pur du focus, pour que le lecteur d'écran annonce quand même « Taille L, indisponible » plutôt que de la sauter en silence — l'utilisateur saura que la taille existe mais est en rupture.
aria-disabled
✓ <option disabled>L — épuisé</option>
✗ Option simplement grisée, sans texte ni état
✗ Variante retirée du DOM sans aucune mention
Annoncer ce qui change (prix, image, stock) au changement de variante
Choisir une variante met souvent à jour, sans recharger la page, le prix, la photo, la référence ou la disponibilité. Pour un utilisateur au lecteur d'écran, ces mises à jour visuelles passent inaperçues s'il n'y a pas de message d'état. Placez la zone de prix/stock dans une région aria-live="polite" (ou un role="status") pour qu'elle soit annoncée sans voler le focus — c'est l'objet de 4.1.3 (Messages d'état, WCAG 2.1 AA).
Si l'image principale change, son alt doit suivre la variante (« Sac camel, vue de face ») — un alt figé qui décrit l'ancienne couleur induit en erreur.
aria-live="polite"
✓ alt de l'image mis à jour avec la variante
✗ Prix qui change visuellement sans aucune annonce
✗ alt figé décrivant une autre couleur
Récapitulatif des critères
| Critère WCAG | Niveau | Application au sélecteur de variantes |
|---|---|---|
| 1.1.1 — Contenu non-texte | A | La pastille de couleur a un équivalent textuel (nom de la couleur) |
| 1.3.1 — Information et relations | A | Chaque jeu d'options forme un groupe nommé (Couleur, Taille…) |
| 1.4.1 — Utilisation de la couleur | A | Ni l'option, ni la sélection, ni la rupture ne reposent sur la couleur seule |
| 1.4.11 — Contraste des éléments non-texte | AA | L'indicateur d'option sélectionnée atteint ≥ 3:1 |
| 2.1.1 — Clavier | A | Toutes les options choisissables au clavier (flèches + Espace/Entrée) |
| 2.4.7 — Visibilité du focus | AA | L'option ciblée au clavier a un focus visible, distinct de la sélection |
| 4.1.2 — Nom, rôle, valeur | A | Vrais contrôles (radio / select) ; état épuisé exposé (aria-disabled) |
| 4.1.3 — Messages d'état | AA | Prix, stock et image annoncés au changement via aria-live |
<span> ou <div>, dont la seule information est la couleur de fond. Pour un utilisateur daltonien, au lecteur d'écran ou en mode contraste élevé, ce sélecteur est totalement opaque — il cumule trois non-conformités : pas de nom (1.1.1), information par la couleur seule (1.4.1), et pas de rôle ni de focus (4.1.2 / 2.1.1). La correction est simple et invisible pour le design : un vrai <input type="radio"> sous la pastille, avec un libellé textuel (« Rouge ») masqué visuellement mais lu par l'assistance.
Comment vérifier
- Clavier seul : sur une fiche produit, atteignez le sélecteur avec Tab, parcourez les options aux flèches, choisissez avec Espace ou Entrée. Vous devez pouvoir choisir couleur ET taille puis ajouter au panier sans souris.
- Lecteur d'écran (NVDA / VoiceOver) : chaque option doit être annoncée avec son nom (« Rouge »), son groupe (« Couleur »), son état (« sélectionné », « indisponible »). Au changement, le prix/stock doit être lu.
- Sans couleur : passez l'écran en niveaux de gris (réglages d'accessibilité du système). Vous devez encore distinguer l'option choisie et les options épuisées.
- Contraste : vérifiez que l'indicateur de sélection (anneau, coche, bordure) atteint ≥ 3:1 avec un vérificateur de contraste ou l'audit axe-core.
Questions fréquentes
Puis-je garder mes jolies pastilles de couleur rondes ?
Oui, totalement. L'accessibilité n'impose pas un style particulier : elle impose que la pastille soit un vrai contrôle (le plus simple est un <input type="radio"> masqué visuellement sous la pastille) et qu'elle porte un nom accessible (« Rouge »). Visuellement, votre sélecteur reste identique ; ce qui change est sous le capot, dans le HTML.
Faut-il une liste déroulante <select> ou des boutons ?
Les deux sont acceptables. Une <select> native est la solution la plus robuste et la moins risquée (accessibilité fournie par le navigateur), idéale pour de longues listes (pointures, contenances). Des boutons radio stylés en pastilles conviennent mieux quand on veut montrer les couleurs ou les tailles d'un coup d'œil — à condition d'utiliser de vrais <input type="radio"> ou le pattern radiogroup correctement câblé.
Comment nommer une couleur multicolore, un imprimé ou un motif ?
Donnez-lui le nom que vous utilisez commercialement : « Imprimé floral », « Multicolore », « Rayé marine ». L'important est qu'un nom textuel existe pour l'option, indépendamment de son rendu visuel. Pour un motif présenté en image, le même principe que 1.1.1 s'applique : l'image de la pastille a besoin d'un équivalent texte.
Une variante épuisée doit-elle disparaître ou rester affichée ?
La rester affichée, signalée comme indisponible, est généralement préférable pour l'accessibilité comme pour l'UX : l'utilisateur sait que la taille existe et qu'elle est en rupture (et peut s'abonner au réapprovisionnement). Affichez « épuisé » en toutes lettres et exposez l'état avec aria-disabled="true" (ou <option disabled>). Une option simplement « grisée » sans texte échoue à 1.4.1 et passe souvent inaperçue.
Le scanner gratuit de DeclareAccess détecte-t-il ces problèmes ?
Partiellement. Le scanner basé sur axe-core détecte fiablement les contrôles sans nom accessible (cas des pastilles en <div>), certains problèmes de rôle/état ARIA et les contrastes insuffisants. En revanche, il ne peut pas juger si une information repose uniquement sur la couleur, ni tester le parcours clavier réel, ni vérifier que le prix est bien annoncé au changement — ces points exigent un test manuel au clavier et au lecteur d'écran.
Lancez le scan automatisé de votre boutique
DeclareAccess analyse une page de votre site selon les WCAG 2.1 AA, vous renvoie un rapport chiffré des non-conformités (avec les éléments concernés), puis génère la déclaration d'accessibilité prête à publier — modèle français (RGAA) ou allemand (BFSG). Audit gratuit, sans carte bancaire.
Rapport WCAG par e-mail sous 24 h ouvrées.
C'est noté. Votre demande d'audit est enregistrée — vous recevrez votre rapport WCAG par e-mail sous 24 h ouvrées.