Checkout-, Adress- und Anmeldefelder brauchen Beschriftungen, automatisches Ausfüllen und verknüpfte Fehlermeldungen

Im Checkout verdient der Shop sein Geld. Ohne Beschriftungen wissen Menschen, die einen Screenreader nutzen, nicht, was sie eingeben sollen; ohne automatisches Ausfüllen müssen Menschen mit motorischen oder Gedächtniseinschränkungen ihre Adresse von Hand eintippen; und wenn Fehlermeldungen nicht mit ihren Feldern verknüpft sind, finden Kundinnen und Kunden nicht heraus, was schiefgelaufen ist, und brechen die Bestellung ab.

Regel-ID
vs-forms-ecommerce
Quelle
Validiscan-Prüfung
Auswirkung
Kritisch
Korrekturstufe
AUTO
auf Shopify, Shopware, WooCommerce und Magento
Status
wird ausgeführt

Was geprüft wird

Prüft Felder in Checkout, Adresse, Kundenkonto und Anmeldung auf fehlende autocomplete-Tokens (1.3.5), fehlende Beschriftungen oder Anleitungen und nicht gekennzeichnete Pflichtfelder (3.3.2) sowie Fehlermeldungen, die nicht mit ihren Feldern verknüpft sind (3.3.1). Ersetzt die axe-Regeln label und autocomplete-valid.

Auf jeder Seite betrachtet die Prüfung jedes input, select und textarea, das assistive Technologien wahrnehmen können, außer versteckten Feldern und Eingaben vom Typ Schaltfläche. Als Beschriftung zählt ein <label>, aria-label, aria-labelledby oder title, ein Platzhalter dagegen nicht. Ob der Text der Beschriftung das Feld zutreffend beschreibt, wird nicht getestet.

Den Zweck eines Feldes vermutet die Prüfung anhand von type, name, id, dem Text der Beschriftung und placeholder. Ist ein Zweck erkannt und hat das Feld kein autocomplete-Token oder steht dort on, off oder ein ungültiges Token, ist das ein Befund. Ausgenommen ist off an einem Passwortfeld. Ein gültiges Token, das vom erwarteten abweicht, ergibt keinen Befund.

Eine Fehlermeldung (role="alert" oder eine Fehlerklasse, neben einem einzelnen Feld) wird gemeldet, wenn sie nicht in einem label steht und weder aria-describedby noch aria-errormessage auf sie verweist. Dasselbe gilt für ein Feld mit aria-invalid="true" ohne verknüpfte Meldung. Ein Pflichtfeld (required oder aria-required="true", Kontrollkästchen und Radiobuttons ausgenommen), dessen Beschriftung weder ein Sternchen noch einen Hinweis auf die Pflichtangabe zeigt, wird gemeldet. Das gilt nicht, wenn das Formular die optionalen Felder kennzeichnet, angibt, dass alle Felder Pflicht sind, oder tatsächlich jedes Feld verlangt. Ein Feld, das nur optisch als Pflichtfeld markiert ist, wird ebenfalls gemeldet.

So wird es behoben

Geben Sie jedem Feld ein sichtbares <label>, das über for und id verknüpft ist, ergänzen Sie das passende autocomplete-Token (given-name, family-name, street-address, postal-code, email, tel, current-password und so weiter), kennzeichnen Sie Pflichtfelder in der Beschriftung und mit dem required-Attribut, und verbinden Sie Fehlermeldungen über aria-describedby und aria-invalid="true" mit ihren Feldern.

WCAG-Erfolgskriterien

Abschnitte der EN 301 549

Der Abschnitt der EN 301 549 zu jedem Kriterium, je Version der Norm
WCAG-Kriterium Version 3.2.1 Version 4.1.1
1.3.5 9.1.3.5 9.1.3.5
3.3.1 9.3.3.1 9.3.3.1
3.3.2 9.3.3.2 9.3.3.2

Wo ein Rezept es behebt

Shopify: Rezept autocomplete-tokens

Vorher und nachher anzeigen (1)
Vorher und nachher Beispieldaten

sections/contact-form.liquid Änderungen an sections/contact-form.liquid: 1 hinzugefügt, 1 entfernt

Änderungen an sections/contact-form.liquid: 1 hinzugefügt, 1 entfernt
Zeile vorher Zeile nachher Änderung Code
14 14 {%- form 'contact', id: 'ContactForm', class: 'contact__form' %}
15 15 <div class="contact__fields">
16 16 <div class="field">
17 Entfernt <input class="field__input" type="text" name="contact[name]" placeholder="{{ 'templates.contact.form.name' | t }}">
17 Hinzugefügt <input class="field__input" type="text" name="contact[name]" placeholder="{{ 'templates.contact.form.name' | t }}" autocomplete="name">
18 18 </div>
19 19 <div class="field">
20 20 <input class="field__input" type="email" name="contact[email]" placeholder="{{ 'templates.contact.form.email' | t }} *" required>

sections/footer.liquid Änderungen an sections/footer.liquid: 1 hinzugefügt, 1 entfernt

Änderungen an sections/footer.liquid: 1 hinzugefügt, 1 entfernt
Zeile vorher Zeile nachher Änderung Code
11 11 {%- form 'customer', id: 'ContactFooter', class: 'footer__newsletter newsletter-form' -%}
12 12 <input type="hidden" name="contact[tags]" value="newsletter">
13 13 <div class="newsletter-form__field-wrapper">
14 Entfernt <input type="email" name="contact[email]" class="field__input" placeholder="{{ 'newsletter.label' | t }}" autocorrect="off" autocapitalize="off">
14 Hinzugefügt <input type="email" name="contact[email]" class="field__input" placeholder="{{ 'newsletter.label' | t }}" autocorrect="off" autocapitalize="off" autocomplete="email">
15 15 <button type="submit" class="button newsletter-form__button" name="commit">{{ 'newsletter.button' | t }}</button>
16 16 </div>
17 17 {%- endform -%}

sections/main-login.liquid Änderungen an sections/main-login.liquid: 1 hinzugefügt, 1 entfernt

Änderungen an sections/main-login.liquid: 1 hinzugefügt, 1 entfernt
Zeile vorher Zeile nachher Änderung Code
10 10 {%- form 'customer_login', novalidate: 'novalidate' %}
11 11 <div class="field">
12 12 <label class="field__label" for="CustomerEmail">{{ 'customer.login_page.email' | t }}</label>
13 Entfernt <input class="field__input" type="email" name="customer[email]" id="CustomerEmail" autocorrect="off" autocapitalize="off">
13 Hinzugefügt <input class="field__input" type="email" name="customer[email]" id="CustomerEmail" autocorrect="off" autocapitalize="off" autocomplete="email">
14 14 </div>
15 15 <div class="field">
16 16 <label class="field__label" for="CustomerPassword">{{ 'customer.login_page.password' | t }}</label>

snippets/checkout-field.liquid Änderungen an snippets/checkout-field.liquid: 4 hinzugefügt, 4 entfernt

Änderungen an snippets/checkout-field.liquid: 4 hinzugefügt, 4 entfernt
Zeile vorher Zeile nachher Änderung Code
15 15 <div class="field">
16 16 {%- case legacy %}
17 17 {%- when 'placeholder' %}
18 Entfernt <input class="field__input" type="{{ field_type }}" id="{{ field_id }}" name="{{ field_name }}" placeholder="{{ label }}"{% if required %} required{% endif %}>
18 Hinzugefügt <input class="field__input" type="{{ field_type }}" id="{{ field_id }}" name="{{ field_name }}" placeholder="{{ label }}"{% if required %} required{% endif %} autocomplete="{{ autocomplete }}">
19 19 {%- when 'starred' %}
20 20 <label class="field__label" for="{{ field_id }}">{{ label }} *</label>
21 Entfernt <input class="field__input" type="{{ field_type }}" id="{{ field_id }}" name="{{ field_name }}">
21 Hinzugefügt <input class="field__input" type="{{ field_type }}" id="{{ field_id }}" name="{{ field_name }}" autocomplete="{{ autocomplete }}">
22 22 {%- when 'off' %}
23 23 <label class="field__label" for="{{ field_id }}">{{ label }}</label>
24 Entfernt <input class="field__input" type="{{ field_type }}" id="{{ field_id }}" name="{{ field_name }}" autocomplete="off"{% if required %} required{% endif %}>
24 Hinzugefügt <input class="field__input" type="{{ field_type }}" id="{{ field_id }}" name="{{ field_name }}" autocomplete="{{ autocomplete }}"{% if required %} required{% endif %}>
25 25 {%- else %}
26 26 <label class="field__label" for="{{ field_id }}">{{ label }}</label>
27 Entfernt <input class="field__input" type="{{ field_type }}" id="{{ field_id }}" name="{{ field_name }}"{% if required %} required{% endif %}>
27 Hinzugefügt <input class="field__input" type="{{ field_type }}" id="{{ field_id }}" name="{{ field_name }}"{% if required %} required{% endif %} autocomplete="{{ autocomplete }}">
28 28 {%- endcase %}
29 29 </div>

Shopify: Rezept label-association

Vorher und nachher anzeigen (1)
Vorher und nachher Beispieldaten

sections/main-collection.liquid Änderungen an sections/main-collection.liquid: 2 hinzugefügt, 2 entfernt

Ä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

Ä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 autocomplete-tokens

Vorher und nachher anzeigen (1)
adds tokens to the register, address, login, contact and newsletter fields; no autocomplete hits remain Beispieldaten

Resources/views/storefront/component/account/login.html.twig Änderungen an Resources/views/storefront/component/account/login.html.twig: 1 hinzugefügt, 1 entfernt

Änderungen an Resources/views/storefront/component/account/login.html.twig: 1 hinzugefügt, 1 entfernt
Zeile vorher Zeile nachher Änderung Code
19 19 name="username"
20 20 placeholder="{{ 'account.loginMailPlaceholder'|trans }}"
21 21 required
22 Entfernt autocomplete="off">
22 Hinzugefügt autocomplete="email">
23 23 </div>
24 24
25 25 <div class="form-group">

Resources/views/storefront/component/account/register.html.twig Änderungen an Resources/views/storefront/component/account/register.html.twig: 8 hinzugefügt, 4 entfernt

Änderungen an Resources/views/storefront/component/account/register.html.twig: 8 hinzugefügt, 4 entfernt
Zeile vorher Zeile nachher Änderung Code
33 33 id="{{ formId }}FirstName"
34 34 name="firstName"
35 35 placeholder="{{ 'account.firstNamePlaceholder'|trans }}"
36 Entfernt required>
36 Hinzugefügt required
37 Hinzugefügt autocomplete="given-name">
37 38 </div>
38 39 <div class="form-group col-sm-6">
39 40 <input type="text"
41 42 id="{{ formId }}LastName"
42 43 name="lastName"
43 44 placeholder="{{ 'account.lastNamePlaceholder'|trans }}"
44 Entfernt required>
45 Hinzugefügt required
46 Hinzugefügt autocomplete="family-name">
45 47 </div>
46 48 </div>
47 49 <div class="row g-2">
52 54 id="{{ formId }}Mail"
53 55 name="email"
54 56 placeholder="{{ 'account.emailPlaceholder'|trans }}"
55 Entfernt required>
57 Hinzugefügt required
58 Hinzugefügt autocomplete="email">
56 59 </div>
57 60 <div class="form-group col-sm-6">
58 61 <label class="form-label" for="{{ formId }}Password">{{ 'account.passwordLabel'|trans }}</label>
62 65 name="password"
63 66 minlength="8"
64 67 aria-describedby="{{ formId }}PasswordHint"
65 Entfernt required>
68 Hinzugefügt required
69 Hinzugefügt autocomplete="new-password">
66 70 <small class="form-text" id="{{ formId }}PasswordHint">{{ 'account.passwordHint'|trans }}</small>
67 71 </div>
68 72 </div>

Resources/views/storefront/component/address/address-form.html.twig Änderungen an Resources/views/storefront/component/address/address-form.html.twig: 8 hinzugefügt, 4 entfernt

Änderungen an Resources/views/storefront/component/address/address-form.html.twig: 8 hinzugefügt, 4 entfernt
Zeile vorher Zeile nachher Änderung Code
14 14 id="{{ prefix }}AddressStreet"
15 15 name="{{ prefix }}[street]"
16 16 placeholder="{{ 'address.streetPlaceholder'|trans }}"
17 Entfernt required>
17 Hinzugefügt required
18 Hinzugefügt autocomplete="address-line1">
18 19 </div>
19 20 {% endblock %}
20 21
26 27 name="{{ prefix }}[zipcode]"
27 28 placeholder="{{ 'address.zipcodePlaceholder'|trans }}"
28 29 inputmode="numeric"
29 Entfernt required>
30 Hinzugefügt required
31 Hinzugefügt autocomplete="postal-code">
30 32 </div>
31 33 {% endblock %}
32 34
37 39 class="form-control"
38 40 id="{{ prefix }}AddressCity"
39 41 name="{{ prefix }}[city]"
40 Entfernt required>
42 Hinzugefügt required
43 Hinzugefügt autocomplete="address-level2">
41 44 </div>
42 45 {% endblock %}
43 46
47 50 <select class="form-select"
48 51 id="{{ prefix }}AddressCountry"
49 52 name="{{ prefix }}[countryId]"
50 Entfernt required>
53 Hinzugefügt required
54 Hinzugefügt autocomplete="country">
51 55 {% for country in countries %}
52 56 <option value="{{ country.id }}"{% if loop.first %} selected{% endif %}>{{ country.name }}</option>
53 57 {% endfor %}

Resources/views/storefront/element/cms-element-form.html.twig Änderungen an Resources/views/storefront/element/cms-element-form.html.twig: 4 hinzugefügt, 4 entfernt

Änderungen an Resources/views/storefront/element/cms-element-form.html.twig: 4 hinzugefügt, 4 entfernt
Zeile vorher Zeile nachher Änderung Code
18 18 </select>
19 19 </div>
20 20 <div class="form-group col-md-4">
21 Entfernt <input type="text" class="form-control" id="contactFormFirstName" name="firstName" placeholder="{{ 'account.firstNamePlaceholder'|trans }}" required>
21 Hinzugefügt <input type="text" class="form-control" id="contactFormFirstName" name="firstName" placeholder="{{ 'account.firstNamePlaceholder'|trans }}" required autocomplete="given-name">
22 22 </div>
23 23 <div class="form-group col-md-4">
24 Entfernt <input type="text" class="form-control" id="contactFormLastName" name="lastName" placeholder="{{ 'account.lastNamePlaceholder'|trans }}" required>
24 Hinzugefügt <input type="text" class="form-control" id="contactFormLastName" name="lastName" placeholder="{{ 'account.lastNamePlaceholder'|trans }}" required autocomplete="family-name">
25 25 </div>
26 26 </div>
27 27
28 28 <div class="row g-2">
29 29 <div class="form-group col-md-6">
30 30 <label class="form-label" for="contactFormMail">{{ 'account.emailLabel'|trans }}</label>
31 Entfernt <input type="email" class="form-control" id="contactFormMail" name="email" placeholder="{{ 'account.emailPlaceholder'|trans }}" required>
31 Hinzugefügt <input type="email" class="form-control" id="contactFormMail" name="email" placeholder="{{ 'account.emailPlaceholder'|trans }}" required autocomplete="email">
32 32 </div>
33 33 <div class="form-group col-md-6">
34 34 <label class="form-label" for="contactFormPhone">{{ 'contact.phoneLabel'|trans }}</label>
35 Entfernt <input type="tel" class="form-control" id="contactFormPhone" name="phone">
35 Hinzugefügt <input type="tel" class="form-control" id="contactFormPhone" name="phone" autocomplete="tel">
36 36 </div>
37 37 </div>
38 38

Resources/views/storefront/layout/footer/footer.html.twig Änderungen an Resources/views/storefront/layout/footer/footer.html.twig: 2 hinzugefügt, 1 entfernt

Änderungen an Resources/views/storefront/layout/footer/footer.html.twig: 2 hinzugefügt, 1 entfernt
Zeile vorher Zeile nachher Änderung Code
62 62 id="footerNewsletterMail"
63 63 class="form-control"
64 64 placeholder="{{ 'footer.newsletterPlaceholder'|trans }}"
65 Entfernt required>
65 Hinzugefügt required
66 Hinzugefügt autocomplete="email">
66 67 <button type="submit" class="btn btn-primary newsletter-submit">{{ 'footer.newsletterSubmit'|trans }}</button>
67 68 </div>
68 69 <div class="form-check newsletter-privacy">

Shopware: Rezept label-association

Vorher und nachher anzeigen (1)
turns the variant group titles into labels of their selects; select-name no longer fires Beispieldaten

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

Ä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 autocomplete-tokens

Vorher und nachher anzeigen (1)
sets the tokens of the login, registration and checkout fields of the fixture theme Beispieldaten

functions.php Änderungen an functions.php: 44 hinzugefügt, 0 entfernt

Änderungen an functions.php: 44 hinzugefügt, 0 entfernt
Zeile vorher Zeile nachher Änderung Code
308 308 * here; the remediation adds one for pages with the _kb_content_language meta and marks the
309 309 * English header and footer with lang="en-GB".
310 310 */
311 Hinzugefügt
312 Hinzugefügt /* validiscan:autocomplete-tokens */
313 Hinzugefügt /**
314 Hinzugefügt * Autocomplete tokens for the WooCommerce address fields, so browsers and assistive
315 Hinzugefügt * technology know what each field asks for (WCAG 1.3.5). Runs after the theme's own
316 Hinzugefügt * field filters.
317 Hinzugefügt *
318 Hinzugefügt * @param array $fields Checkout fields (grouped by section) or one address section.
319 Hinzugefügt * @return array
320 Hinzugefügt */
321 Hinzugefügt function kb_address_autocomplete( $fields ) {
322 Hinzugefügt $tokens = array(
323 Hinzugefügt 'first_name' => 'given-name',
324 Hinzugefügt 'last_name' => 'family-name',
325 Hinzugefügt 'company' => 'organization',
326 Hinzugefügt 'country' => 'country',
327 Hinzugefügt 'address_1' => 'address-line1',
328 Hinzugefügt 'address_2' => 'address-line2',
329 Hinzugefügt 'city' => 'address-level2',
330 Hinzugefügt 'state' => 'address-level1',
331 Hinzugefügt 'postcode' => 'postal-code',
332 Hinzugefügt 'phone' => 'tel',
333 Hinzugefügt 'email' => 'email',
334 Hinzugefügt );
335 Hinzugefügt foreach ( $fields as $key => $field ) {
336 Hinzugefügt if ( ! is_array( $field ) ) {
337 Hinzugefügt continue;
338 Hinzugefügt }
339 Hinzugefügt if ( 'billing' === $key || 'shipping' === $key ) {
340 Hinzugefügt $fields[ $key ] = kb_address_autocomplete( $field );
341 Hinzugefügt continue;
342 Hinzugefügt }
343 Hinzugefügt if ( ! preg_match( '/^(billing|shipping)_(.+)$/', (string) $key, $match ) || ! isset( $tokens[ $match[2] ] ) ) {
344 Hinzugefügt continue;
345 Hinzugefügt }
346 Hinzugefügt $fields[ $key ]['autocomplete'] = ( 'shipping' === $match[1] ? 'shipping ' : '' ) . $tokens[ $match[2] ];
347 Hinzugefügt unset( $fields[ $key ]['custom_attributes']['autocomplete'] );
348 Hinzugefügt }
349 Hinzugefügt return $fields;
350 Hinzugefügt }
351 Hinzugefügt add_filter( 'woocommerce_checkout_fields', 'kb_address_autocomplete', 99 );
352 Hinzugefügt add_filter( 'woocommerce_billing_fields', 'kb_address_autocomplete', 99 );
353 Hinzugefügt add_filter( 'woocommerce_shipping_fields', 'kb_address_autocomplete', 99 );
354 Hinzugefügt /* /validiscan:autocomplete-tokens */

woocommerce/myaccount/form-login.php Änderungen an woocommerce/myaccount/form-login.php: 3 hinzugefügt, 3 entfernt

Änderungen an woocommerce/myaccount/form-login.php: 3 hinzugefügt, 3 entfernt
Zeile vorher Zeile nachher Änderung Code
29 29
30 30 <p class="woocommerce-form-row woocommerce-form-row--wide form-row form-row-wide">
31 31 <label for="username"><?php esc_html_e( 'Username or email address', 'woocommerce' ); ?>&nbsp;<span class="required">*</span></label>
32 Entfernt <input type="text" class="woocommerce-Input woocommerce-Input--text input-text" name="username" id="username" autocomplete="off" value="<?php echo ( ! empty( $_POST['username'] ) ) ? esc_attr( wp_unslash( $_POST['username'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Missing,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized ?>">
32 Hinzugefügt <input type="text" class="woocommerce-Input woocommerce-Input--text input-text" name="username" id="username" autocomplete="username" value="<?php echo ( ! empty( $_POST['username'] ) ) ? esc_attr( wp_unslash( $_POST['username'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Missing,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized ?>">
33 33 </p>
34 34 <p class="woocommerce-form-row woocommerce-form-row--wide form-row form-row-wide">
35 35 <label for="password"><?php esc_html_e( 'Password', 'woocommerce' ); ?>&nbsp;<span class="required">*</span></label>
36 36 <span class="password-input">
37 Entfernt <input class="woocommerce-Input woocommerce-Input--text input-text" type="password" name="password" id="password" autocomplete="off" onpaste="return false;">
37 Hinzugefügt <input class="woocommerce-Input woocommerce-Input--text input-text" type="password" name="password" id="password" autocomplete="current-password" onpaste="return false;">
38 38 <button type="button" class="show-password-input"><?php kb_icon( 'eye' ); ?></button>
39 39 </span>
40 40 </p>
63 63 <?php do_action( 'woocommerce_register_form_start' ); ?>
64 64
65 65 <p class="woocommerce-form-row woocommerce-form-row--wide form-row form-row-wide">
66 Entfernt <input type="email" class="woocommerce-Input woocommerce-Input--text input-text" name="email" id="reg_email" autocomplete="off" value="" placeholder="<?php esc_attr_e( 'Email address *', 'kestrel-birch' ); ?>">
66 Hinzugefügt <input type="email" class="woocommerce-Input woocommerce-Input--text input-text" name="email" id="reg_email" autocomplete="email" value="" placeholder="<?php esc_attr_e( 'Email address *', 'kestrel-birch' ); ?>">
67 67 </p>
68 68 <p><?php esc_html_e( 'A link to set a new password will be sent to your email address.', 'woocommerce' ); ?></p>
69 69

WooCommerce: Rezept label-association

Vorher und nachher anzeigen (1)
ties an unassociated coupon label to its field, as in the fixed cart Beispieldaten

woocommerce/cart/cart.php Änderungen an woocommerce/cart/cart.php: 1 hinzugefügt, 1 entfernt

Ä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 autocomplete-tokens

Vorher und nachher anzeigen (1)
adds tokens to the newsletter, login and contact forms and validates Beispieldaten

app/design/frontend/Validiscan/fixture/Magento_Contact/templates/form.phtml Änderungen an app/design/frontend/Validiscan/fixture/Magento_Contact/templates/form.phtml: 3 hinzugefügt, 3 entfernt

Änderungen an app/design/frontend/Validiscan/fixture/Magento_Contact/templates/form.phtml: 3 hinzugefügt, 3 entfernt
Zeile vorher Zeile nachher Änderung Code
21 21 <!-- VALIDISCAN-SEEDED vs-forms-ecommerce: name, email and phone lack autocomplete; required only via the CSS asterisk -->
22 22 <div class="field name required">
23 23 <label class="label" for="name"><span><?= $escaper->escapeHtml(__('Name')) ?></span></label>
24 Entfernt <div class="control"><input name="name" id="name" title="<?= $escaper->escapeHtmlAttr(__('Name')) ?>" value="<?= $escaper->escapeHtmlAttr($viewModel->getUserName()) ?>" class="input-text" type="text"></div>
24 Hinzugefügt <div class="control"><input name="name" id="name" title="<?= $escaper->escapeHtmlAttr(__('Name')) ?>" value="<?= $escaper->escapeHtmlAttr($viewModel->getUserName()) ?>" class="input-text" type="text" autocomplete="name"></div>
25 25 </div>
26 26 <div class="field email required">
27 27 <label class="label" for="email"><span><?= $escaper->escapeHtml(__('Email')) ?></span></label>
28 Entfernt <div class="control"><input name="email" id="email" title="<?= $escaper->escapeHtmlAttr(__('Email')) ?>" value="<?= $escaper->escapeHtmlAttr($viewModel->getUserEmail()) ?>" class="input-text" type="email"></div>
28 Hinzugefügt <div class="control"><input name="email" id="email" title="<?= $escaper->escapeHtmlAttr(__('Email')) ?>" value="<?= $escaper->escapeHtmlAttr($viewModel->getUserEmail()) ?>" class="input-text" type="email" autocomplete="email"></div>
29 29 </div>
30 30 <div class="field telephone">
31 31 <label class="label" for="telephone"><span><?= $escaper->escapeHtml(__('Phone Number')) ?></span></label>
32 Entfernt <div class="control"><input name="telephone" id="telephone" title="<?= $escaper->escapeHtmlAttr(__('Phone Number')) ?>" value="<?= $escaper->escapeHtmlAttr($viewModel->getUserTelephone()) ?>" class="input-text" type="tel"></div>
32 Hinzugefügt <div class="control"><input name="telephone" id="telephone" title="<?= $escaper->escapeHtmlAttr(__('Phone Number')) ?>" value="<?= $escaper->escapeHtmlAttr($viewModel->getUserTelephone()) ?>" class="input-text" type="tel" autocomplete="tel"></div>
33 33 </div>
34 34 <div class="field comment required">
35 35 <label class="label" for="comment"><span><?= $escaper->escapeHtml(__('What’s on your mind?')) ?></span></label>

app/design/frontend/Validiscan/fixture/Magento_Customer/templates/form/login.phtml Änderungen an app/design/frontend/Validiscan/fixture/Magento_Customer/templates/form/login.phtml: 2 hinzugefügt, 2 entfernt

Änderungen an app/design/frontend/Validiscan/fixture/Magento_Customer/templates/form/login.phtml: 2 hinzugefügt, 2 entfernt
Zeile vorher Zeile nachher Änderung Code
27 27 <div class="field email required">
28 28 <label class="label" for="email"><span><?= $escaper->escapeHtml(__('Email')) ?></span></label>
29 29 <div class="control">
30 Entfernt <input name="login[username]" value="<?= $escaper->escapeHtmlAttr($username) ?>" autocomplete="off" id="email" type="email" class="input-text mage-error" title="<?= $escaper->escapeHtmlAttr(__('Email')) ?>" aria-invalid="true" tabindex="1" onpaste="return false;" data-mage-init='{"mage/trim-input":{}}'>
30 Hinzugefügt <input name="login[username]" value="<?= $escaper->escapeHtmlAttr($username) ?>" autocomplete="email" id="email" type="email" class="input-text mage-error" title="<?= $escaper->escapeHtmlAttr(__('Email')) ?>" aria-invalid="true" tabindex="1" onpaste="return false;" data-mage-init='{"mage/trim-input":{}}'>
31 31 <div for="email" generated="true" class="mage-error" id="email-error"><?= $escaper->escapeHtml(__('Please enter a valid email address (Ex: johndoe@domain.com).')) ?></div>
32 32 </div>
33 33 </div>
35 35 <div class="field password required">
36 36 <label for="pass" class="label"><span><?= $escaper->escapeHtml(__('Password')) ?></span></label>
37 37 <div class="control">
38 Entfernt <input name="login[password]" type="password" autocomplete="off" class="input-text" id="pass" title="<?= $escaper->escapeHtmlAttr(__('Password')) ?>" tabindex="2" onpaste="return false;" oncopy="return false;">
38 Hinzugefügt <input name="login[password]" type="password" autocomplete="current-password" class="input-text" id="pass" title="<?= $escaper->escapeHtmlAttr(__('Password')) ?>" tabindex="2" onpaste="return false;" oncopy="return false;">
39 39 </div>
40 40 </div>
41 41 <!-- VALIDISCAN-SEEDED vs-accessible-auth: arithmetic CAPTCHA with no alternative -->

app/design/frontend/Validiscan/fixture/Magento_Newsletter/templates/subscribe.phtml Änderungen an app/design/frontend/Validiscan/fixture/Magento_Newsletter/templates/subscribe.phtml: 1 hinzugefügt, 1 entfernt

Änderungen an app/design/frontend/Validiscan/fixture/Magento_Newsletter/templates/subscribe.phtml: 1 hinzugefügt, 1 entfernt
Zeile vorher Zeile nachher Änderung Code
18 18 <!-- VALIDISCAN-SEEDED vs-forms-ecommerce (label): newsletter email only has a placeholder, no label and no autocomplete -->
19 19 <div class="field newsletter">
20 20 <div class="control">
21 Entfernt <input name="email" type="email" id="newsletter" placeholder="<?= $escaper->escapeHtmlAttr(__('Enter your email address')) ?>" data-mage-init='{"mage/trim-input":{}}' data-validate="{required:true, 'validate-email':true}">
21 Hinzugefügt <input name="email" type="email" id="newsletter" placeholder="<?= $escaper->escapeHtmlAttr(__('Enter your email address')) ?>" data-mage-init='{"mage/trim-input":{}}' data-validate="{required:true, 'validate-email':true}" autocomplete="email">
22 22 </div>
23 23 </div>
24 24 <div class="actions">

Magento: Rezept label-association

Vorher und nachher anzeigen (1)
turns the "Sort By" text into the sorter label and validates Beispieldaten

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

Ä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 anfordern

Oder 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

Nachricht an Validiscan

Für einen kostenlosen Check nennen Sie die Adresse Ihres Shops und seine Plattform.

Validiscan verwendet, was Sie senden, um Ihnen zu antworten. Datenschutzerklärung