Les éléments select doivent avoir un nom accessible

Les listes déroulantes de taille, de couleur, de quantité, de pays ou de tri ont besoin d’un nom. Sans nom, les personnes qui utilisent un lecteur d’écran n’entendent que « zone de liste » et ne savent pas ce qu’elles choisissent, ce qui entraîne des erreurs de commande ou les empêche de finaliser leur achat.

Identifiant de la règle
select-name
Source
axe-core 4.13.0
Impact
Critique
Niveau de correction
ASSISTED
sur Shopify, Shopware, WooCommerce et Magento
Statut
exécutée

Ce que fait le contrôle

Vérifier que les éléments select ont un nom accessible

La règle teste chaque <select> que les technologies d’assistance peuvent atteindre ; une liste déroulante masquée avec display: none est ignorée. Un <select> réussit avec l’une de ces sources :

  • un <label> englobant qui contient son propre texte
  • un <label> avec du texte, dont le for correspond à l’id du <select>
  • un aria-label avec du texte, un aria-labelledby qui aboutit à du texte, ou un title avec du texte
  • role="none" ou role="presentation", mais seulement sur un <select> qui ne peut pas recevoir le focus, par exemple un <select> désactivé

Le texte des options ne compte jamais : un <label> ou un aria-labelledby dont le seul texte provient des options du <select> lui-même échoue.

Un <label for> masqué aux technologies d’assistance met le <select> en échec, sauf si une autre source le nomme malgré tout. Une étiquette masquée visuellement, mais que les lecteurs d’écran peuvent lire, est acceptée.

Quand aucune source ne nomme le <select> et que l’un de ces contrôles ne peut pas aboutir, le résultat va dans la liste « à examiner » d’axe-core, que le scanner de Validiscan ne transforme pas en constats pour l’instant. La règle ne juge pas si le nom indique au client ce qu’il choisit.

Comment corriger

Associez un <label> à chaque <select> au moyen d’attributs for et id correspondants, ou donnez-lui un aria-label ou un aria-labelledby, par exemple <label for="size">Taille</label>. Reprenez le texte de l’étiquette dans les noms d’options traduits de la boutique.

Critères de succès WCAG

Clauses de la norme EN 301 549

La clause de la norme EN 301 549 pour chaque critère, selon la version de la norme
Critère WCAG Version 3.2.1 Version 4.1.1
4.1.2 9.4.1.2 9.4.1.2

Recettes qui énumèrent cette règle

Cette règle a le niveau ASSISTED. Dans un projet, un constat de cette règle suit la voie ASSISTED, et ces recettes ne lui sont pas appliquées.

Shopify : recette label-association

Afficher l’avant et l’après (1)
Avant et après Données d’exemple

sections/main-collection.liquid Modifications apportées à sections/main-collection.liquid (lignes ajoutées : 2, lignes supprimées : 2)

Modifications apportées à sections/main-collection.liquid (lignes ajoutées : 2, lignes supprimées : 2)
Ligne avant Ligne après Modification Code
64 64 <div class="collection__products">
65 65 <div class="collection__toolbar">
66 66 <div class="collection__sort">
67 Supprimée <label class="collection__sort-label">Sort by</label>
68 Supprimée <select name="sort_by" class="select__select" form="FacetFiltersForm">
67 Ajoutée <label class="collection__sort-label" for="SortBy-{{ section.id }}">Sort by</label>
68 Ajoutée <select name="sort_by" class="select__select" form="FacetFiltersForm" id="SortBy-{{ section.id }}">
69 69 <option value="manual" selected>Featured</option>
70 70 <option value="best-selling">Best selling</option>
71 71 <option value="price-ascending">Price, low to high</option>

sections/main-product.liquid Modifications apportées à sections/main-product.liquid (lignes ajoutées : 2, lignes supprimées : 2)

Modifications apportées à sections/main-product.liquid (lignes ajoutées : 2, lignes supprimées : 2)
Ligne avant Ligne après Modification Code
94 94 </div>
95 95 {%- else %}
96 96 <div class="product-form__input product-form__input--dropdown">
97 Supprimée <p class="form__label">{{ option.name | escape }}</p>
97 Ajoutée <p class="form__label" id="Options-{{ section.id }}-{{ forloop.index0 }}-label">{{ option.name | escape }}</p>
98 98 <div class="select">
99 Supprimée <select class="select__select" name="options[{{ option.name | escape }}]" data-option-index="{{ option_index }}">
99 Ajoutée <select class="select__select" name="options[{{ option.name | escape }}]" data-option-index="{{ option_index }}" aria-labelledby="Options-{{ section.id }}-{{ forloop.index0 }}-label">
100 100 {%- for value in option.values %}
101 101 <option value="{{ value | escape }}"{% if value == option.selected_value %} selected{% endif %}>{{ value | escape }}</option>
102 102 {%- endfor %}

Shopware : recette label-association

Afficher l’avant et l’après (1)
turns the variant group titles into labels of their selects; select-name no longer fires Données d’exemple

Resources/views/storefront/page/product-detail/configurator.html.twig Modifications apportées à Resources/views/storefront/page/product-detail/configurator.html.twig (lignes ajoutées : 1, lignes supprimées : 1)

Modifications apportées à Resources/views/storefront/page/product-detail/configurator.html.twig (lignes ajoutées : 1, lignes supprimées : 1)
Ligne avant Ligne après Modification Code
13 13 {% for group in product.configurator %}
14 14 {% if group.display == 'select' %}
15 15 <div class="product-detail-configurator-group">
16 Supprimée <div class="product-detail-configurator-group-title">{{ group.name }}</div>
16 Ajoutée <label class="product-detail-configurator-group-title" for="configurator-{{ group.id }}">{{ group.name }}</label>
17 17 <select class="form-select product-detail-configurator-select-input"
18 18 id="configurator-{{ group.id }}"
19 19 name="{{ group.id }}"{% if group.price|default(false) %}

WooCommerce : recette label-association

Afficher l’avant et l’après (1)
ties an unassociated coupon label to its field, as in the fixed cart Données d’exemple

woocommerce/cart/cart.php Modifications apportées à woocommerce/cart/cart.php (lignes ajoutées : 1, lignes supprimées : 1)

Modifications apportées à woocommerce/cart/cart.php (lignes ajoutées : 1, lignes supprimées : 1)
Ligne avant Ligne après Modification Code
62 62 <tr>
63 63 <td colspan="6" class="actions">
64 64 <div class="coupon">
65 Supprimée <label class="screen-reader-text"><?php esc_html_e( 'Coupon:', 'woocommerce' ); ?></label>
65 Ajoutée <label class="screen-reader-text" for="coupon_code"><?php esc_html_e( 'Coupon:', 'woocommerce' ); ?></label>
66 66 <input type="text" name="coupon_code" class="input-text" id="coupon_code" value="" placeholder="<?php esc_attr_e( 'Coupon code', 'woocommerce' ); ?>">
67 67 <button type="submit" class="button" name="apply_coupon" value="<?php esc_attr_e( 'Apply coupon', 'woocommerce' ); ?>"><?php esc_html_e( 'Apply coupon', 'woocommerce' ); ?></button>
68 68 </div>

Magento : recette label-association

Afficher l’avant et l’après (1)
turns the "Sort By" text into the sorter label and validates Données d’exemple

app/design/frontend/Validiscan/fixture/Magento_Catalog/templates/product/list/toolbar.phtml Modifications apportées à app/design/frontend/Validiscan/fixture/Magento_Catalog/templates/product/list/toolbar.phtml (lignes ajoutées : 1, lignes supprimées : 1)

Modifications apportées à app/design/frontend/Validiscan/fixture/Magento_Catalog/templates/product/list/toolbar.phtml (lignes ajoutées : 1, lignes supprimées : 1)
Ligne avant Ligne après Modification Code
12 12 <div class="toolbar-sorter sorter">
13 13 <!-- VALIDISCAN-SEEDED select-name + vs-forms-ecommerce: the "Sort By" text is a span, not a label for the select -->
14 14 <?php /* Fixed variant: <label class="sorter-label" for="sorter">Sort By</label>. */ ?>
15 Supprimée <span class="sorter-label"><?= $escaper->escapeHtml(__('Sort By')) ?></span>
15 Ajoutée <label class="sorter-label" for="sorter"><?= $escaper->escapeHtml(__('Sort By')) ?></label>
16 16 <select id="sorter" data-role="sorter" class="sorter-options">
17 17 <?php foreach ($block->getAvailableOrders() as $key => $order): ?>
18 18 <option value="<?= $escaper->escapeHtmlAttr($key) ?>"<?= $block->isOrderCurrent($key) ? ' selected' : '' ?>><?= $escaper->escapeHtml(__($order)) ?></option>

Commencez par une vérification gratuite de votre boutique.

Envoyez l’adresse de votre boutique. Validiscan la scanne et vous envoie chaque échec que le scan peut prouver, avec sa page et son code.

Demander une vérification gratuite

Ou écrivez à info@validiscan.com.

Ce que couvre la vérification gratuite, et ce qu’elle laisse de côté
Vous envoyez
l’adresse de votre boutique
Pages scannées
jusqu’à 15
Vous recevez
chaque échec que le scan peut prouver, avec la page et le code
Sur votre boutique
pages publiques uniquement ; aucune connexion, aucun achat, aucun formulaire envoyé
Ce qu’elle n’est pas
un audit complet

Écrire à Validiscan

Pour une vérification gratuite, indiquez l’adresse de votre boutique et sa plateforme.

Validiscan utilise ce que vous envoyez pour vous répondre. Politique de confidentialité