Los campos de pago, dirección e inicio de sesión necesitan etiquetas, autocompletado y errores vinculados

Es en el proceso de pago donde la tienda gana su dinero. Sin etiquetas, quienes usan un lector de pantalla no saben qué escribir; sin autocompletado, las personas con discapacidad motriz o con problemas de memoria tienen que escribir su dirección a mano; y cuando los errores no están vinculados a sus campos, los clientes no encuentran qué ha fallado y abandonan el pedido.

ID de la regla
vs-forms-ecommerce
Origen
Comprobación de Validiscan
Impacto
Crítico
Nivel de corrección
AUTO
en Shopify, Shopware, WooCommerce y Magento
Estado
se ejecuta

Qué hace la comprobación

Revisa los campos del proceso de pago, de dirección, de cuenta y de inicio de sesión en busca de tokens de autocomplete que faltan (1.3.5), etiquetas o instrucciones que faltan y campos obligatorios que no se indican como tales (3.3.2), y mensajes de error que no están asociados a sus campos (3.3.1). Sustituye a las reglas de axe label y autocomplete-valid.

En todas las páginas, la comprobación examina cada input, select y textarea que los productos de apoyo pueden percibir, salvo los campos ocultos y los de tipo botón. Una etiqueta cuenta si procede de <label>, aria-label, aria-labelledby o title, no de un placeholder. No se prueba si el texto de la etiqueta describe el campo.

La finalidad de un campo se deduce de su type, su name, su id, el texto de su etiqueta y su placeholder. Una finalidad reconocida sin token de autocomplete, o con on, off o un token no válido, es un hallazgo, salvo off en un campo de contraseña; un token válido pero distinto no lo es.

Un mensaje de error (role="alert" o una clase de error, junto a un único campo) se notifica cuando no está dentro de un label y ningún aria-describedby ni aria-errormessage lo referencia; lo mismo ocurre con un campo con aria-invalid="true" sin mensaje vinculado. Se notifica un campo obligatorio (required o aria-required="true", salvo las casillas de verificación y los botones de opción) cuya etiqueta no muestra ni un asterisco ni un texto que lo indique como obligatorio, a menos que el formulario marque los campos opcionales, indique que todos son obligatorios o exija todos los campos. Un campo marcado como obligatorio solo visualmente también se notifica.

Cómo corregirlo

Dé a cada campo un <label> visible vinculado mediante for e id, añada el token de autocomplete correspondiente (given-name, family-name, street-address, postal-code, email, tel, current-password, etc.), marque los campos obligatorios en la etiqueta y con el atributo required, y vincule los mensajes de error a sus campos con aria-describedby y aria-invalid="true".

Criterios de conformidad de las WCAG

Apartados de la norma EN 301 549

El apartado de la norma EN 301 549 que corresponde a cada criterio, por versión de la norma
Criterio de las WCAG Versión 3.2.1 Versión 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

Dónde lo corrige una receta

Shopify: receta autocomplete-tokens

Mostrar el antes y el después (1)
Antes y después Datos de ejemplo

sections/contact-form.liquid Cambios en sections/contact-form.liquid (líneas añadidas: 1; eliminadas: 1)

Cambios en sections/contact-form.liquid (líneas añadidas: 1; eliminadas: 1)
Línea anterior Línea nueva Cambio Código
14 14 {%- form 'contact', id: 'ContactForm', class: 'contact__form' %}
15 15 <div class="contact__fields">
16 16 <div class="field">
17 Eliminada <input class="field__input" type="text" name="contact[name]" placeholder="{{ 'templates.contact.form.name' | t }}">
17 Añadida <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 Cambios en sections/footer.liquid (líneas añadidas: 1; eliminadas: 1)

Cambios en sections/footer.liquid (líneas añadidas: 1; eliminadas: 1)
Línea anterior Línea nueva Cambio Código
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 Eliminada <input type="email" name="contact[email]" class="field__input" placeholder="{{ 'newsletter.label' | t }}" autocorrect="off" autocapitalize="off">
14 Añadida <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 Cambios en sections/main-login.liquid (líneas añadidas: 1; eliminadas: 1)

Cambios en sections/main-login.liquid (líneas añadidas: 1; eliminadas: 1)
Línea anterior Línea nueva Cambio Código
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 Eliminada <input class="field__input" type="email" name="customer[email]" id="CustomerEmail" autocorrect="off" autocapitalize="off">
13 Añadida <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 Cambios en snippets/checkout-field.liquid (líneas añadidas: 4; eliminadas: 4)

Cambios en snippets/checkout-field.liquid (líneas añadidas: 4; eliminadas: 4)
Línea anterior Línea nueva Cambio Código
15 15 <div class="field">
16 16 {%- case legacy %}
17 17 {%- when 'placeholder' %}
18 Eliminada <input class="field__input" type="{{ field_type }}" id="{{ field_id }}" name="{{ field_name }}" placeholder="{{ label }}"{% if required %} required{% endif %}>
18 Añadida <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 Eliminada <input class="field__input" type="{{ field_type }}" id="{{ field_id }}" name="{{ field_name }}">
21 Añadida <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 Eliminada <input class="field__input" type="{{ field_type }}" id="{{ field_id }}" name="{{ field_name }}" autocomplete="off"{% if required %} required{% endif %}>
24 Añadida <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 Eliminada <input class="field__input" type="{{ field_type }}" id="{{ field_id }}" name="{{ field_name }}"{% if required %} required{% endif %}>
27 Añadida <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: receta label-association

Mostrar el antes y el después (1)
Antes y después Datos de ejemplo

sections/main-collection.liquid Cambios en sections/main-collection.liquid (líneas añadidas: 2; eliminadas: 2)

Cambios en sections/main-collection.liquid (líneas añadidas: 2; eliminadas: 2)
Línea anterior Línea nueva Cambio Código
64 64 <div class="collection__products">
65 65 <div class="collection__toolbar">
66 66 <div class="collection__sort">
67 Eliminada <label class="collection__sort-label">Sort by</label>
68 Eliminada <select name="sort_by" class="select__select" form="FacetFiltersForm">
67 Añadida <label class="collection__sort-label" for="SortBy-{{ section.id }}">Sort by</label>
68 Añadida <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 Cambios en sections/main-product.liquid (líneas añadidas: 2; eliminadas: 2)

Cambios en sections/main-product.liquid (líneas añadidas: 2; eliminadas: 2)
Línea anterior Línea nueva Cambio Código
94 94 </div>
95 95 {%- else %}
96 96 <div class="product-form__input product-form__input--dropdown">
97 Eliminada <p class="form__label">{{ option.name | escape }}</p>
97 Añadida <p class="form__label" id="Options-{{ section.id }}-{{ forloop.index0 }}-label">{{ option.name | escape }}</p>
98 98 <div class="select">
99 Eliminada <select class="select__select" name="options[{{ option.name | escape }}]" data-option-index="{{ option_index }}">
99 Añadida <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: receta autocomplete-tokens

Mostrar el antes y el después (1)
adds tokens to the register, address, login, contact and newsletter fields; no autocomplete hits remain Datos de ejemplo

Resources/views/storefront/component/account/login.html.twig Cambios en Resources/views/storefront/component/account/login.html.twig (líneas añadidas: 1; eliminadas: 1)

Cambios en Resources/views/storefront/component/account/login.html.twig (líneas añadidas: 1; eliminadas: 1)
Línea anterior Línea nueva Cambio Código
19 19 name="username"
20 20 placeholder="{{ 'account.loginMailPlaceholder'|trans }}"
21 21 required
22 Eliminada autocomplete="off">
22 Añadida autocomplete="email">
23 23 </div>
24 24
25 25 <div class="form-group">

Resources/views/storefront/component/account/register.html.twig Cambios en Resources/views/storefront/component/account/register.html.twig (líneas añadidas: 8; eliminadas: 4)

Cambios en Resources/views/storefront/component/account/register.html.twig (líneas añadidas: 8; eliminadas: 4)
Línea anterior Línea nueva Cambio Código
33 33 id="{{ formId }}FirstName"
34 34 name="firstName"
35 35 placeholder="{{ 'account.firstNamePlaceholder'|trans }}"
36 Eliminada required>
36 Añadida required
37 Añadida 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 Eliminada required>
45 Añadida required
46 Añadida 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 Eliminada required>
57 Añadida required
58 Añadida 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 Eliminada required>
68 Añadida required
69 Añadida 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 Cambios en Resources/views/storefront/component/address/address-form.html.twig (líneas añadidas: 8; eliminadas: 4)

Cambios en Resources/views/storefront/component/address/address-form.html.twig (líneas añadidas: 8; eliminadas: 4)
Línea anterior Línea nueva Cambio Código
14 14 id="{{ prefix }}AddressStreet"
15 15 name="{{ prefix }}[street]"
16 16 placeholder="{{ 'address.streetPlaceholder'|trans }}"
17 Eliminada required>
17 Añadida required
18 Añadida 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 Eliminada required>
30 Añadida required
31 Añadida 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 Eliminada required>
42 Añadida required
43 Añadida 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 Eliminada required>
53 Añadida required
54 Añadida 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 Cambios en Resources/views/storefront/element/cms-element-form.html.twig (líneas añadidas: 4; eliminadas: 4)

Cambios en Resources/views/storefront/element/cms-element-form.html.twig (líneas añadidas: 4; eliminadas: 4)
Línea anterior Línea nueva Cambio Código
18 18 </select>
19 19 </div>
20 20 <div class="form-group col-md-4">
21 Eliminada <input type="text" class="form-control" id="contactFormFirstName" name="firstName" placeholder="{{ 'account.firstNamePlaceholder'|trans }}" required>
21 Añadida <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 Eliminada <input type="text" class="form-control" id="contactFormLastName" name="lastName" placeholder="{{ 'account.lastNamePlaceholder'|trans }}" required>
24 Añadida <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 Eliminada <input type="email" class="form-control" id="contactFormMail" name="email" placeholder="{{ 'account.emailPlaceholder'|trans }}" required>
31 Añadida <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 Eliminada <input type="tel" class="form-control" id="contactFormPhone" name="phone">
35 Añadida <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 Cambios en Resources/views/storefront/layout/footer/footer.html.twig (líneas añadidas: 2; eliminadas: 1)

Cambios en Resources/views/storefront/layout/footer/footer.html.twig (líneas añadidas: 2; eliminadas: 1)
Línea anterior Línea nueva Cambio Código
62 62 id="footerNewsletterMail"
63 63 class="form-control"
64 64 placeholder="{{ 'footer.newsletterPlaceholder'|trans }}"
65 Eliminada required>
65 Añadida required
66 Añadida 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: receta label-association

Mostrar el antes y el después (1)
turns the variant group titles into labels of their selects; select-name no longer fires Datos de ejemplo

Resources/views/storefront/page/product-detail/configurator.html.twig Cambios en Resources/views/storefront/page/product-detail/configurator.html.twig (líneas añadidas: 1; eliminadas: 1)

Cambios en Resources/views/storefront/page/product-detail/configurator.html.twig (líneas añadidas: 1; eliminadas: 1)
Línea anterior Línea nueva Cambio Código
13 13 {% for group in product.configurator %}
14 14 {% if group.display == 'select' %}
15 15 <div class="product-detail-configurator-group">
16 Eliminada <div class="product-detail-configurator-group-title">{{ group.name }}</div>
16 Añadida <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: receta autocomplete-tokens

Mostrar el antes y el después (1)
sets the tokens of the login, registration and checkout fields of the fixture theme Datos de ejemplo

functions.php Cambios en functions.php (líneas añadidas: 44; eliminadas: 0)

Cambios en functions.php (líneas añadidas: 44; eliminadas: 0)
Línea anterior Línea nueva Cambio Código
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 Añadida
312 Añadida /* validiscan:autocomplete-tokens */
313 Añadida /**
314 Añadida * Autocomplete tokens for the WooCommerce address fields, so browsers and assistive
315 Añadida * technology know what each field asks for (WCAG 1.3.5). Runs after the theme's own
316 Añadida * field filters.
317 Añadida *
318 Añadida * @param array $fields Checkout fields (grouped by section) or one address section.
319 Añadida * @return array
320 Añadida */
321 Añadida function kb_address_autocomplete( $fields ) {
322 Añadida $tokens = array(
323 Añadida 'first_name' => 'given-name',
324 Añadida 'last_name' => 'family-name',
325 Añadida 'company' => 'organization',
326 Añadida 'country' => 'country',
327 Añadida 'address_1' => 'address-line1',
328 Añadida 'address_2' => 'address-line2',
329 Añadida 'city' => 'address-level2',
330 Añadida 'state' => 'address-level1',
331 Añadida 'postcode' => 'postal-code',
332 Añadida 'phone' => 'tel',
333 Añadida 'email' => 'email',
334 Añadida );
335 Añadida foreach ( $fields as $key => $field ) {
336 Añadida if ( ! is_array( $field ) ) {
337 Añadida continue;
338 Añadida }
339 Añadida if ( 'billing' === $key || 'shipping' === $key ) {
340 Añadida $fields[ $key ] = kb_address_autocomplete( $field );
341 Añadida continue;
342 Añadida }
343 Añadida if ( ! preg_match( '/^(billing|shipping)_(.+)$/', (string) $key, $match ) || ! isset( $tokens[ $match[2] ] ) ) {
344 Añadida continue;
345 Añadida }
346 Añadida $fields[ $key ]['autocomplete'] = ( 'shipping' === $match[1] ? 'shipping ' : '' ) . $tokens[ $match[2] ];
347 Añadida unset( $fields[ $key ]['custom_attributes']['autocomplete'] );
348 Añadida }
349 Añadida return $fields;
350 Añadida }
351 Añadida add_filter( 'woocommerce_checkout_fields', 'kb_address_autocomplete', 99 );
352 Añadida add_filter( 'woocommerce_billing_fields', 'kb_address_autocomplete', 99 );
353 Añadida add_filter( 'woocommerce_shipping_fields', 'kb_address_autocomplete', 99 );
354 Añadida /* /validiscan:autocomplete-tokens */

woocommerce/myaccount/form-login.php Cambios en woocommerce/myaccount/form-login.php (líneas añadidas: 3; eliminadas: 3)

Cambios en woocommerce/myaccount/form-login.php (líneas añadidas: 3; eliminadas: 3)
Línea anterior Línea nueva Cambio Código
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 Eliminada <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 Añadida <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 Eliminada <input class="woocommerce-Input woocommerce-Input--text input-text" type="password" name="password" id="password" autocomplete="off" onpaste="return false;">
37 Añadida <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 Eliminada <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 Añadida <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: receta label-association

Mostrar el antes y el después (1)
ties an unassociated coupon label to its field, as in the fixed cart Datos de ejemplo

woocommerce/cart/cart.php Cambios en woocommerce/cart/cart.php (líneas añadidas: 1; eliminadas: 1)

Cambios en woocommerce/cart/cart.php (líneas añadidas: 1; eliminadas: 1)
Línea anterior Línea nueva Cambio Código
62 62 <tr>
63 63 <td colspan="6" class="actions">
64 64 <div class="coupon">
65 Eliminada <label class="screen-reader-text"><?php esc_html_e( 'Coupon:', 'woocommerce' ); ?></label>
65 Añadida <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: receta autocomplete-tokens

Mostrar el antes y el después (1)
adds tokens to the newsletter, login and contact forms and validates Datos de ejemplo

app/design/frontend/Validiscan/fixture/Magento_Contact/templates/form.phtml Cambios en app/design/frontend/Validiscan/fixture/Magento_Contact/templates/form.phtml (líneas añadidas: 3; eliminadas: 3)

Cambios en app/design/frontend/Validiscan/fixture/Magento_Contact/templates/form.phtml (líneas añadidas: 3; eliminadas: 3)
Línea anterior Línea nueva Cambio Código
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 Eliminada <div class="control"><input name="name" id="name" title="<?= $escaper->escapeHtmlAttr(__('Name')) ?>" value="<?= $escaper->escapeHtmlAttr($viewModel->getUserName()) ?>" class="input-text" type="text"></div>
24 Añadida <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 Eliminada <div class="control"><input name="email" id="email" title="<?= $escaper->escapeHtmlAttr(__('Email')) ?>" value="<?= $escaper->escapeHtmlAttr($viewModel->getUserEmail()) ?>" class="input-text" type="email"></div>
28 Añadida <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 Eliminada <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 Añadida <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 Cambios en app/design/frontend/Validiscan/fixture/Magento_Customer/templates/form/login.phtml (líneas añadidas: 2; eliminadas: 2)

Cambios en app/design/frontend/Validiscan/fixture/Magento_Customer/templates/form/login.phtml (líneas añadidas: 2; eliminadas: 2)
Línea anterior Línea nueva Cambio Código
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 Eliminada <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 Añadida <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 Eliminada <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 Añadida <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 Cambios en app/design/frontend/Validiscan/fixture/Magento_Newsletter/templates/subscribe.phtml (líneas añadidas: 1; eliminadas: 1)

Cambios en app/design/frontend/Validiscan/fixture/Magento_Newsletter/templates/subscribe.phtml (líneas añadidas: 1; eliminadas: 1)
Línea anterior Línea nueva Cambio Código
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 Eliminada <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 Añadida <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: receta label-association

Mostrar el antes y el después (1)
turns the "Sort By" text into the sorter label and validates Datos de ejemplo

app/design/frontend/Validiscan/fixture/Magento_Catalog/templates/product/list/toolbar.phtml Cambios en app/design/frontend/Validiscan/fixture/Magento_Catalog/templates/product/list/toolbar.phtml (líneas añadidas: 1; eliminadas: 1)

Cambios en app/design/frontend/Validiscan/fixture/Magento_Catalog/templates/product/list/toolbar.phtml (líneas añadidas: 1; eliminadas: 1)
Línea anterior Línea nueva Cambio Código
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 Eliminada <span class="sorter-label"><?= $escaper->escapeHtml(__('Sort By')) ?></span>
15 Añadida <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>

Empiece con una revisión gratuita de su tienda.

Envíe la dirección de su tienda. Validiscan la escanea y le responde con cada fallo que el escaneo pueda demostrar, con la página y el código.

Solicitar revisión gratuita

O escriba a info@validiscan.com.

Qué cubre la revisión gratuita y qué deja fuera
Usted envía
la dirección de su tienda
Páginas escaneadas
hasta 15
Usted recibe
todos los fallos que el escaneo puede demostrar, con la página y el código
En su tienda
solo páginas públicas; sin inicio de sesión, nada comprado, ningún formulario enviado
Lo que no es
una auditoría completa

Escribir a Validiscan

Para una revisión gratuita, indique la dirección web de su tienda y su plataforma.

Validiscan utiliza lo que usted envía para responderle. Política de privacidad