Auswahlfelder müssen einen zugänglichen Namen haben
Auswahlmenüs für Größe, Farbe, Menge, Land oder Sortierung brauchen einen Namen. Ohne ihn hören Kundinnen und Kunden mit Screenreader nur „Kombinationsfeld“ und wissen nicht, was sie gerade auswählen. Das führt zu falschen Bestellungen oder blockiert den Checkout.
- Regel-ID
- select-name
- Quelle
- axe-core 4.13.0
- Auswirkung
- Kritisch
- Korrekturstufe
- ASSISTED
- auf Shopify, Shopware, WooCommerce und Magento
- Status
- wird ausgeführt
Was geprüft wird
Sicherstellen, dass select-Elemente einen zugänglichen Namen haben
Die Regel testet jedes <select>, das assistive Technologien erreichen können; ein Auswahlfeld, das mit display: none verborgen ist, wird übersprungen. Ein Auswahlfeld besteht mit einer dieser Angaben:
- einem umschließenden
<label>mit eigenem Text - einem
<label>mit Text, dessenforzuriddes Auswahlfelds passt - einem
aria-labelmit Text, einemaria-labelledby, das Text ergibt, oder einemtitlemit Text role="none"oderrole="presentation", aber nur bei einem Auswahlfeld, das keinen Fokus erhalten kann, etwa einem deaktivierten
Der Text der Optionen zählt nie: Stammt der einzige Text eines <label> oder aria-labelledby aus den Optionen des Auswahlfelds selbst, gilt das Auswahlfeld als Verstoß.
Ist ein <label for> vor assistiven Technologien verborgen, gilt das Auswahlfeld als Verstoß, es sei denn, eine andere Quelle benennt es noch. Eine visuell verborgene Beschriftung, die Screenreader lesen können, wird akzeptiert.
Benennt keine Quelle das Auswahlfeld und lässt sich eine dieser Prüfungen nicht abschließen, landet das Ergebnis bei axe-core in der Liste „zu prüfen“. Daraus macht der Scanner von Validiscan derzeit keine Befunde. Ob der Name Kundinnen und Kunden sagt, was sie gerade auswählen, beurteilt die Regel nicht.
So wird es behoben
Verknüpfen Sie jedes <select> über übereinstimmende for- und id-Attribute mit einem <label> oder geben Sie ihm aria-label oder aria-labelledby, zum Beispiel <label for="size">Größe</label>. Nehmen Sie den Beschriftungstext aus den übersetzten Optionsnamen des Shops.
WCAG-Erfolgskriterien
- 4.1.2 Name, Role, Value, Stufe A
Abschnitte der EN 301 549
| WCAG-Kriterium | Version 3.2.1 | Version 4.1.1 |
|---|---|---|
| 4.1.2 | 9.4.1.2 | 9.4.1.2 |
Rezepte, die diese Regel aufführen
Diese Regel hat die Korrekturstufe ASSISTED. In einem Projekt geht ein Befund dieser Regel den Weg ASSISTED, und diese Rezepte werden darauf nicht angewendet.
Shopify: Rezept label-association
Vorher und nachher anzeigen (1)
sections/main-collection.liquid Änderungen an sections/main-collection.liquid: 2 hinzugefügt, 2 entfernt
| Zeile vorher | Zeile nachher | Änderung | Code |
|---|---|---|---|
| 64 | 64 | <div class="collection__products"> | |
| 65 | 65 | <div class="collection__toolbar"> | |
| 66 | 66 | <div class="collection__sort"> | |
| 67 | Entfernt | <label class="collection__sort-label">Sort by</label> | |
| 68 | Entfernt | <select name="sort_by" class="select__select" form="FacetFiltersForm"> | |
| 67 | Hinzugefügt | <label class="collection__sort-label" for="SortBy-{{ section.id }}">Sort by</label> | |
| 68 | Hinzugefügt | <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 Änderungen an sections/main-product.liquid: 2 hinzugefügt, 2 entfernt
| Zeile vorher | Zeile nachher | Änderung | Code |
|---|---|---|---|
| 94 | 94 | </div> | |
| 95 | 95 | {%- else %} | |
| 96 | 96 | <div class="product-form__input product-form__input--dropdown"> | |
| 97 | Entfernt | <p class="form__label">{{ option.name | escape }}</p> | |
| 97 | Hinzugefügt | <p class="form__label" id="Options-{{ section.id }}-{{ forloop.index0 }}-label">{{ option.name | escape }}</p> | |
| 98 | 98 | <div class="select"> | |
| 99 | Entfernt | <select class="select__select" name="options[{{ option.name | escape }}]" data-option-index="{{ option_index }}"> | |
| 99 | Hinzugefügt | <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: Rezept label-association
Vorher und nachher anzeigen (1)
Resources/views/storefront/page/product-detail/configurator.html.twig Änderungen an Resources/views/storefront/page/product-detail/configurator.html.twig: 1 hinzugefügt, 1 entfernt
| Zeile vorher | Zeile nachher | Änderung | Code |
|---|---|---|---|
| 13 | 13 | {% for group in product.configurator %} | |
| 14 | 14 | {% if group.display == 'select' %} | |
| 15 | 15 | <div class="product-detail-configurator-group"> | |
| 16 | Entfernt | <div class="product-detail-configurator-group-title">{{ group.name }}</div> | |
| 16 | Hinzugefügt | <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: Rezept label-association
Vorher und nachher anzeigen (1)
woocommerce/cart/cart.php Änderungen an woocommerce/cart/cart.php: 1 hinzugefügt, 1 entfernt
| Zeile vorher | Zeile nachher | Änderung | Code |
|---|---|---|---|
| 62 | 62 | <tr> | |
| 63 | 63 | <td colspan="6" class="actions"> | |
| 64 | 64 | <div class="coupon"> | |
| 65 | Entfernt | <label class="screen-reader-text"><?php esc_html_e( 'Coupon:', 'woocommerce' ); ?></label> | |
| 65 | Hinzugefügt | <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: Rezept label-association
Vorher und nachher anzeigen (1)
app/design/frontend/Validiscan/fixture/Magento_Catalog/templates/product/list/toolbar.phtml Änderungen an app/design/frontend/Validiscan/fixture/Magento_Catalog/templates/product/list/toolbar.phtml: 1 hinzugefügt, 1 entfernt
| Zeile vorher | Zeile nachher | Änderung | 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 | Entfernt | <span class="sorter-label"><?= $escaper->escapeHtml(__('Sort By')) ?></span> | |
| 15 | Hinzugefügt | <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> |
Beginnen Sie mit einem kostenlosen Check Ihres Shops.
Senden Sie die Adresse Ihres Shops. Validiscan scannt ihn und antwortet mit jedem Fehler, den der Scan nachweisen kann, jeweils mit der Seite und dem Code.
Kostenlosen Check anfordernOder schreiben Sie an info@validiscan.com.
Was der kostenlose Check umfasst und was nicht- Sie senden
- die Adresse Ihres Shops
- Gescannte Seiten
- bis zu 15
- Sie erhalten
- jeden Fehler, den der Scan nachweisen kann, mit Seite und Code
- In Ihrem Shop
- nur öffentliche Seiten; keine Anmeldung, nichts gekauft, kein Formular abgeschickt
- Was er nicht ist
- ein vollständiges Audit