El banner de cookies debe poder usarse con el teclado y gestionar correctamente el foco
El banner de cookies es lo primero que encuentra cualquier visitante. Cuando quienes usan el teclado o un lector de pantalla no pueden llegar a sus botones, no pueden cerrarlo o pierden su posición al cerrarse, se quedan bloqueados antes de haber visto un solo producto, y la mayoría abandona la tienda.
- ID de la regla
- vs-cookie-banner
- Origen
- Comprobación de Validiscan
- Impacto
- Crítico
- Nivel de corrección
- ASSISTED
- en Shopify, Shopware, WooCommerce y Magento
- Estado
- se ejecuta
Qué hace la comprobación
Comprueba que el banner o cuadro de diálogo de consentimiento se puede alcanzar y usar con el teclado, mantiene el foco dentro mientras bloquea la página, ofrece un control de cierre alcanzable o la tecla Escape, tiene un nombre accesible y un contraste suficiente, y devuelve el foco a la página al cerrarse.
Un banner es un recuadro con texto y controles: el contenedor de una plataforma de consentimiento, o bien un cuadro de diálogo, un elemento fijo o sticky, o un elemento absoluto con un z-index alto, cuyo id, clase o texto mencione las cookies, el consentimiento o la privacidad. Como el escáner acepta los banners de forma predeterminada, una página que no muestra ninguno se vuelve a abrir sin cookies, una vez por escaneo y viewport.
Si el foco no entra en el banner en un máximo de 30 pulsaciones de Tab desde el principio de la página, es un hallazgo. Un banner es modal si tiene aria-modal, si es un <dialog> modal, si bloquea el desplazamiento de la página o si lleva una capa que cubre todo el viewport; en ese caso debe contener ya el foco o recibirlo con la primera pulsación de Tab.
En una copia desechable de la página, Escape debe cerrar un banner modal que no sea un <dialog> nativo y que no tenga ningún control enfocable para rechazar o cerrar, y el control de rechazar, cerrar o aceptar se prueba con Enter, con la barra espaciadora y después con un clic. Que se cierre solo con el clic es un hallazgo, y también lo es que el foco acabe en el cuerpo de la página tras cerrarlo con el teclado. Los resultados no concluyentes pasan a «pendiente de revisión», que hoy no genera ningún hallazgo.
Cómo corregirlo
Use elementos <button> reales para aceptar, rechazar y configurar; dé al banner role="dialog" con un nombre (aria-labelledby apuntando a su encabezado); lleve el foco a su interior al abrirse, mantenga Tab dentro mientras bloquea la página, permita cerrarlo con Escape y devuelva el foco adonde estaba el visitante. La mayoría de los banners proceden de una plataforma de consentimiento: active su diseño accesible o sus opciones de accesibilidad antes de modificar el código del tema.
Criterios de conformidad de las WCAG
- 2.1.1 Keyboard, nivel A
- 2.1.2 No Keyboard Trap, nivel A
- 2.4.3 Focus Order, nivel A
- 4.1.2 Name, Role, Value, nivel A
Apartados de la norma EN 301 549
| Criterio de las WCAG | Versión 3.2.1 | Versión 4.1.1 |
|---|---|---|
| 2.1.1 | 9.2.1.1 | 9.2.1.1 |
| 2.1.2 | 9.2.1.2 | 9.2.1.2 |
| 2.4.3 | 9.2.4.3 | 9.2.4.3 |
| 4.1.2 | 9.4.1.2 | 9.4.1.2 |
Recetas que enumeran esta regla
Esta regla tiene el nivel ASSISTED. En un proyecto, un hallazgo de esta regla sigue la vía ASSISTED, y estas recetas no se le aplican.
Shopify: receta button-semantics
Mostrar el antes y el después (1)
assets/base.css.liquid Cambios en assets/base.css.liquid (líneas añadidas: 14; eliminadas: 0)
| Línea anterior | Línea nueva | Cambio | Código |
|---|---|---|---|
| 1866 | 1866 | } | |
| 1867 | 1867 | ||
| 1868 | 1868 | /* ----------------------------------------------------------------- motion */ | |
| 1869 | Añadida | ||
| 1870 | Añadida | /* validiscan:button-semantics */ | |
| 1871 | Añadida | :where(button.slider-counter__link) { | |
| 1872 | Añadida | appearance: none; | |
| 1873 | Añadida | margin: 0; | |
| 1874 | Añadida | padding: 0; | |
| 1875 | Añadida | border: 0; | |
| 1876 | Añadida | background: none; | |
| 1877 | Añadida | color: inherit; | |
| 1878 | Añadida | font: inherit; | |
| 1879 | Añadida | text-align: inherit; | |
| 1880 | Añadida | cursor: pointer; | |
| 1881 | Añadida | } | |
| 1882 | Añadida | /* /validiscan:button-semantics */ |
sections/slideshow.liquid Cambios en sections/slideshow.liquid (líneas añadidas: 1; eliminadas: 1)
| Línea anterior | Línea nueva | Cambio | Código |
|---|---|---|---|
| 62 | 62 | </button> | |
| 63 | 63 | <div class="slider-counter"> | |
| 64 | 64 | {%- for block in section.blocks %} | |
| 65 | Eliminada | <span class="slider-counter__link" data-slide-to="{{ forloop.index0 }}"><span class="dot"></span></span> | |
| 65 | Añadida | <button class="slider-counter__link" data-slide-to="{{ forloop.index0 }}" type="button"><span class="dot"></span><span class="visually-hidden">{{ 'accessibility.load_slide' | t: index: forloop.index, count: forloop.length }}</span></button> | |
| 66 | 66 | {%- endfor %} | |
| 67 | 67 | </div> | |
| 68 | 68 | <button type="button" class="slider-button slider-button--next" name="next" data-slide-next> |
Shopify: receta icon-accessible-name
Mostrar el antes y el después (2)
locales/en.default.json Cambios en locales/en.default.json (líneas añadidas: 3; eliminadas: 1)
| Línea anterior | Línea nueva | Cambio | Código |
|---|---|---|---|
| 34 | 34 | "total_reviews": "{{ count }} reviews", | |
| 35 | 35 | "link_messages": { | |
| 36 | 36 | "new_window": "Opens in a new window." | |
| 37 | Eliminada | } | |
| 37 | Añadida | }, | |
| 38 | Añadida | "accept_cookies": "Accept cookies", | |
| 39 | Añadida | "reject_cookies": "Reject cookies" | |
| 38 | 40 | }, | |
| 39 | 41 | "sections": { | |
| 40 | 42 | "header": { |
sections/header.liquid Cambios en sections/header.liquid (líneas añadidas: 1; eliminadas: 0)
| Línea anterior | Línea nueva | Cambio | Código |
|---|---|---|---|
| 40 | 40 | <input class="search__input field__input" type="search" name="q" value="" placeholder="{{ 'general.search.placeholder' | t }}" tabindex="1"> | |
| 41 | 41 | <button type="submit" class="search__button"> | |
| 42 | 42 | {%- render 'icon', icon: 'search', size: 20 -%} | |
| 43 | Añadida | <span class="visually-hidden">{{ 'general.search.search' | t }}</span> | |
| 43 | 44 | </button> | |
| 44 | 45 | </form> | |
| 45 | 46 | </div> |
sections/main-product.liquid Cambios en sections/main-product.liquid (líneas añadidas: 1; eliminadas: 1)
| Línea anterior | Línea nueva | Cambio | Código |
|---|---|---|---|
| 88 | 88 | <p class="form__label">{{ option.name | escape }}</p> | |
| 89 | 89 | <div class="swatch-list swatch-list--compact"> | |
| 90 | 90 | {%- for swatch in option.swatches %} | |
| 91 | Eliminada | <button type="button" class="swatch swatch--button{% if swatch.selected %} swatch--active{% endif %}" style="--swatch-color: {{ swatch.color }};" data-option-index="{{ option_index }}" data-value="{{ swatch.value | escape }}"></button> | |
| 91 | Añadida | <button type="button" class="swatch swatch--button{% if swatch.selected %} swatch--active{% endif %}" style="--swatch-color: {{ swatch.color }};" data-option-index="{{ option_index }}" data-value="{{ swatch.value | escape }}"><span class="visually-hidden">{{ swatch.value | escape }}</span></button> | |
| 92 | 92 | {%- endfor %} | |
| 93 | 93 | </div> | |
| 94 | 94 | </div> |
sections/slideshow.liquid Cambios en sections/slideshow.liquid (líneas añadidas: 2; eliminadas: 0)
| Línea anterior | Línea nueva | Cambio | Código |
|---|---|---|---|
| 59 | 59 | <div class="slideshow__controls"> | |
| 60 | 60 | <button type="button" class="slider-button slider-button--prev" name="previous" data-slide-prev> | |
| 61 | 61 | {%- render 'icon', icon: 'chevron-left', size: 20 -%} | |
| 62 | Añadida | <span class="visually-hidden">{{ 'accessibility.previous_slide' | t }}</span> | |
| 62 | 63 | </button> | |
| 63 | 64 | <div class="slider-counter"> | |
| 64 | 65 | {%- for block in section.blocks %} | |
| 67 | 68 | </div> | |
| 68 | 69 | <button type="button" class="slider-button slider-button--next" name="next" data-slide-next> | |
| 69 | 70 | {%- render 'icon', icon: 'chevron-right', size: 20 -%} | |
| 71 | Añadida | <span class="visually-hidden">{{ 'accessibility.next_slide' | t }}</span> | |
| 70 | 72 | </button> | |
| 71 | 73 | </div> | |
| 72 | 74 | </slideshow-component> |
snippets/cookie-banner.liquid Cambios en snippets/cookie-banner.liquid (líneas añadidas: 2; eliminadas: 0)
| Línea anterior | Línea nueva | Cambio | Código |
|---|---|---|---|
| 23 | 23 | <div class="cookie-banner__actions"> | |
| 24 | 24 | <button type="button" class="cookie-banner__icon-button cookie-banner__icon-button--accept" data-cookie-accept> | |
| 25 | 25 | {%- render 'icon', icon: 'check', size: 20 -%} | |
| 26 | Añadida | <span class="visually-hidden">{{ 'accessibility.accept_cookies' | t }}</span> | |
| 26 | 27 | </button> | |
| 27 | 28 | <button type="button" class="cookie-banner__icon-button" data-cookie-reject> | |
| 28 | 29 | {%- render 'icon', icon: 'close', size: 20 -%} | |
| 30 | Añadida | <span class="visually-hidden">{{ 'accessibility.reject_cookies' | t }}</span> | |
| 29 | 31 | </button> | |
| 30 | 32 | </div> | |
| 31 | 33 | </div> |
snippets/quantity-input.liquid Cambios en snippets/quantity-input.liquid (líneas añadidas: 2; eliminadas: 0)
| Línea anterior | Línea nueva | Cambio | Código |
|---|---|---|---|
| 9 | 9 | {%- endcomment -%} | |
| 10 | 10 | <div class="quantity quantity--compact" data-quantity{% if line %} data-line="{{ line }}"{% endif %}><button class="quantity__button" name="minus" type="button" data-quantity-minus> | |
| 11 | 11 | {%- render 'icon', icon: 'minus', size: 12 -%} | |
| 12 | Añadida | <span class="visually-hidden">{{ 'products.product.quantity.decrease' | t: product: product_title }}</span> | |
| 12 | 13 | </button> | |
| 13 | 14 | <input class="quantity__input" type="number" name="{{ input_name }}" id="{{ input_id }}" value="{{ value | default: 1 }}" min="{% if line %}0{% else %}1{% endif %}" data-quantity-input> | |
| 14 | 15 | <button class="quantity__button" name="plus" type="button" data-quantity-plus> | |
| 15 | 16 | {%- render 'icon', icon: 'plus', size: 12 -%} | |
| 17 | Añadida | <span class="visually-hidden">{{ 'products.product.quantity.increase' | t: product: product_title }}</span> | |
| 16 | 18 | </button></div> |
sections/footer.liquid Cambios en sections/footer.liquid (líneas añadidas: 1; eliminadas: 0)
| Línea anterior | Línea nueva | Cambio | Código |
|---|---|---|---|
| 37 | 37 | {%- for social in shop.social %} | |
| 38 | 38 | <a href="{{ social.url }}" class="list-social__link link"> | |
| 39 | 39 | {%- render 'icon', icon: social.icon, size: 20 -%} | |
| 40 | Añadida | <span class="visually-hidden">{{ 'general.social.links.' | append: social.icon | t }}</span> | |
| 40 | 41 | </a> | |
| 41 | 42 | {%- endfor %} | |
| 42 | 43 | </ul> |
sections/header.liquid Cambios en sections/header.liquid (líneas añadidas: 3; eliminadas: 1)
| Línea anterior | Línea nueva | Cambio | Código |
|---|---|---|---|
| 22 | 22 | </details> | |
| 23 | 23 | ||
| 24 | 24 | {% if logo_is_heading %}<h1 class="header__heading">{% else %}<div class="header__heading">{% endif %} | |
| 25 | Eliminada | <a href="{{ routes.root_url }}" class="header__heading-link"><img src="{{ 'logo.svg' | asset_url }}" width="{{ settings.logo_width }}" height="32" class="header__heading-logo"></a> | |
| 25 | Añadida | <a href="{{ routes.root_url }}" class="header__heading-link"><img src="{{ 'logo.svg' | asset_url }}" width="{{ settings.logo_width }}" height="32" class="header__heading-logo" alt="{{ shop.name | escape }}"></a> | |
| 26 | 26 | {% if logo_is_heading %}</h1>{% else %}</div>{% endif %} | |
| 27 | 27 | ||
| 28 | 28 | <nav class="header__inline-menu"> | |
| 50 | 50 | {%- endif %} | |
| 51 | 51 | <a href="{{ routes.account_login_url }}" class="header__icon header__icon--account link"> | |
| 52 | 52 | {%- render 'icon', icon: 'account', size: icon_size -%} | |
| 53 | Añadida | <span class="visually-hidden">{{ 'sections.header.account' | t }}</span> | |
| 53 | 54 | </a> | |
| 54 | 55 | <a href="{{ routes.cart_url }}" class="header__icon header__icon--cart link" id="cart-icon-bubble"> | |
| 55 | 56 | {%- render 'icon', icon: 'cart', size: icon_size -%} | |
| 57 | 58 | <span class="cart-count-bubble" aria-hidden="true"><span data-cart-count>{{ cart.item_count }}</span></span> | |
| 58 | 59 | {%- endif -%} | |
| 59 | 60 | ||
| 61 | Añadida | <span class="visually-hidden">{{ 'sections.header.cart' | t }}</span> | |
| 60 | 62 | </a> | |
| 61 | 63 | </div> | |
| 62 | 64 | </header> |
sections/main-cart.liquid Cambios en sections/main-cart.liquid (líneas añadidas: 1; eliminadas: 0)
| Línea anterior | Línea nueva | Cambio | Código |
|---|---|---|---|
| 26 | 26 | {% render 'quantity-input', input_id: qty_id, input_name: 'updates[]', value: item.quantity, product_title: item.product.title, line: line %} | |
| 27 | 27 | <a href="{{ routes.cart_change_url }}?line={{ line }}&quantity=0" class="cart-item__remove cart-item__remove--compact" data-cart-remove> | |
| 28 | 28 | {%- render 'icon', icon: 'trash', size: 16 -%} | |
| 29 | Añadida | <span class="visually-hidden">{{ 'sections.cart.remove' | t: title: item.product.title }}</span> | |
| 29 | 30 | </a> | |
| 30 | 31 | </div> | |
| 31 | 32 | <div class="cart-item__totals"> |
Shopware: receta button-semantics
Mostrar el antes y el después (1)
Resources/app/storefront/src/scss/base.scss Cambios en Resources/app/storefront/src/scss/base.scss (líneas añadidas: 17; eliminadas: 0)
| Línea anterior | Línea nueva | Cambio | Código |
|---|---|---|---|
| 1708 | 1708 | margin: 8px 0 0; | |
| 1709 | 1709 | font-size: 0.875rem; | |
| 1710 | 1710 | } | |
| 1711 | Añadida | ||
| 1712 | Añadida | /* validiscan:button-semantics */ | |
| 1713 | Añadida | /* Former <div>/<span>/<li> controls, now <button>: drop the browser button styles, keep the theme's (no specificity). */ | |
| 1714 | Añadida | :where(button.base-slider-dot) { | |
| 1715 | Añadida | display: block; | |
| 1716 | Añadida | margin: 0; | |
| 1717 | Añadida | padding: 0; | |
| 1718 | Añadida | border: 0; | |
| 1719 | Añadida | background: none; | |
| 1720 | Añadida | color: inherit; | |
| 1721 | Añadida | font: inherit; | |
| 1722 | Añadida | line-height: inherit; | |
| 1723 | Añadida | text-align: inherit; | |
| 1724 | Añadida | cursor: pointer; | |
| 1725 | Añadida | appearance: none; | |
| 1726 | Añadida | } | |
| 1727 | Añadida | /* /validiscan:button-semantics */ |
Resources/snippet/de_DE/kaffeekontor-nord.de-DE.json Cambios en Resources/snippet/de_DE/kaffeekontor-nord.de-DE.json (líneas añadidas: 5; eliminadas: 0)
| Línea anterior | Línea nueva | Cambio | Código |
|---|---|---|---|
| 193 | 193 | "notFoundText": "Die gesuchte Seite existiert nicht oder wurde verschoben.", | |
| 194 | 194 | "backToHome": "Zurück zur Startseite", | |
| 195 | 195 | "searchInstead": "Unsere Kaffees durchsuchen" | |
| 196 | Añadida | }, | |
| 197 | Añadida | "a11y": { | |
| 198 | Añadida | "control": { | |
| 199 | Añadida | "showSlide": "Folie %index% anzeigen" | |
| 200 | Añadida | } | |
| 196 | 201 | } | |
| 197 | 202 | } |
Resources/snippet/en_GB/kaffeekontor-nord.en-GB.json Cambios en Resources/snippet/en_GB/kaffeekontor-nord.en-GB.json (líneas añadidas: 5; eliminadas: 0)
| Línea anterior | Línea nueva | Cambio | Código |
|---|---|---|---|
| 193 | 193 | "notFoundText": "The page you are looking for does not exist or has moved.", | |
| 194 | 194 | "backToHome": "Back to the homepage", | |
| 195 | 195 | "searchInstead": "Search our coffees" | |
| 196 | Añadida | }, | |
| 197 | Añadida | "a11y": { | |
| 198 | Añadida | "control": { | |
| 199 | Añadida | "showSlide": "Show slide %index%" | |
| 200 | Añadida | } | |
| 196 | 201 | } | |
| 197 | 202 | } |
Resources/views/storefront/element/cms-element-image-slider.html.twig Cambios en Resources/views/storefront/element/cms-element-image-slider.html.twig (líneas añadidas: 1; eliminadas: 1)
| Línea anterior | Línea nueva | Cambio | Código |
|---|---|---|---|
| 51 | 51 | </button> | |
| 52 | 52 | <ol class="base-slider-dots"> | |
| 53 | 53 | {% for slide in slides %} | |
| 54 | Eliminada | <li class="base-slider-dot{% if loop.first %} is-active{% endif %}" data-slide-to="{{ loop.index0 }}"></li> | |
| 54 | Añadida | <li><button class="base-slider-dot{% if loop.first %} is-active{% endif %}" data-slide-to="{{ loop.index0 }}" type="button" aria-label="{{ 'a11y.control.showSlide'|trans({'%index%': loop.index})|striptags }}"></button></li> | |
| 55 | 55 | {% endfor %} | |
| 56 | 56 | </ol> | |
| 57 | 57 | <button type="button" class="base-slider-controls-next image-slider-controls-btn" data-slide-next> |
Shopware: receta icon-accessible-name
Mostrar el antes y el después (2)
Resources/snippet/de_DE/kaffeekontor-nord.de-DE.json Cambios en Resources/snippet/de_DE/kaffeekontor-nord.de-DE.json (líneas añadidas: 12; eliminadas: 0)
| Línea anterior | Línea nueva | Cambio | Código |
|---|---|---|---|
| 193 | 193 | "notFoundText": "Die gesuchte Seite existiert nicht oder wurde verschoben.", | |
| 194 | 194 | "backToHome": "Zurück zur Startseite", | |
| 195 | 195 | "searchInstead": "Unsere Kaffees durchsuchen" | |
| 196 | Añadida | }, | |
| 197 | Añadida | "a11y": { | |
| 198 | Añadida | "control": { | |
| 199 | Añadida | "search": "Suchen", | |
| 200 | Añadida | "previousSlide": "Vorherige Folie", | |
| 201 | Añadida | "nextSlide": "Nächste Folie", | |
| 202 | Añadida | "cookieSettings": "Cookie-Einstellungen", | |
| 203 | Añadida | "acceptCookies": "Alle Cookies akzeptieren", | |
| 204 | Añadida | "decreaseQuantity": "Menge verringern", | |
| 205 | Añadida | "increaseQuantity": "Menge erhöhen", | |
| 206 | Añadida | "removeFromCart": "Aus dem Warenkorb entfernen" | |
| 207 | Añadida | } | |
| 196 | 208 | } | |
| 197 | 209 | } |
Resources/snippet/en_GB/kaffeekontor-nord.en-GB.json Cambios en Resources/snippet/en_GB/kaffeekontor-nord.en-GB.json (líneas añadidas: 12; eliminadas: 0)
| Línea anterior | Línea nueva | Cambio | Código |
|---|---|---|---|
| 193 | 193 | "notFoundText": "The page you are looking for does not exist or has moved.", | |
| 194 | 194 | "backToHome": "Back to the homepage", | |
| 195 | 195 | "searchInstead": "Search our coffees" | |
| 196 | Añadida | }, | |
| 197 | Añadida | "a11y": { | |
| 198 | Añadida | "control": { | |
| 199 | Añadida | "search": "Search", | |
| 200 | Añadida | "previousSlide": "Previous slide", | |
| 201 | Añadida | "nextSlide": "Next slide", | |
| 202 | Añadida | "cookieSettings": "Cookie settings", | |
| 203 | Añadida | "acceptCookies": "Accept all cookies", | |
| 204 | Añadida | "decreaseQuantity": "Decrease quantity", | |
| 205 | Añadida | "increaseQuantity": "Increase quantity", | |
| 206 | Añadida | "removeFromCart": "Remove from cart" | |
| 207 | Añadida | } | |
| 196 | 208 | } | |
| 197 | 209 | } |
Resources/views/storefront/element/cms-element-image-gallery.html.twig Cambios en Resources/views/storefront/element/cms-element-image-gallery.html.twig (líneas añadidas: 2; eliminadas: 2)
| Línea anterior | Línea nueva | Cambio | Código |
|---|---|---|---|
| 31 | 31 | ||
| 32 | 32 | {% if media|length > 1 %} | |
| 33 | 33 | <div class="gallery-slider-controls"> | |
| 34 | Eliminada | <button type="button" class="base-slider-controls-prev gallery-slider-controls-prev" data-gallery-prev> | |
| 34 | Añadida | <button type="button" class="base-slider-controls-prev gallery-slider-controls-prev" data-gallery-prev aria-label="{{ 'a11y.control.previousSlide'|trans|striptags }}"> | |
| 35 | 35 | {% sw_icon 'arrow-head-left' %} | |
| 36 | 36 | </button> | |
| 37 | Eliminada | <button type="button" class="base-slider-controls-next gallery-slider-controls-next" data-gallery-next> | |
| 37 | Añadida | <button type="button" class="base-slider-controls-next gallery-slider-controls-next" data-gallery-next aria-label="{{ 'a11y.control.nextSlide'|trans|striptags }}"> | |
| 38 | 38 | {% sw_icon 'arrow-head-right' %} | |
| 39 | 39 | </button> | |
| 40 | 40 | </div> |
Resources/views/storefront/element/cms-element-image-slider.html.twig Cambios en Resources/views/storefront/element/cms-element-image-slider.html.twig (líneas añadidas: 2; eliminadas: 2)
| Línea anterior | Línea nueva | Cambio | Código |
|---|---|---|---|
| 46 | 46 | ||
| 47 | 47 | {% block element_image_slider_controls %} | |
| 48 | 48 | <div class="image-slider-controls-container"> | |
| 49 | Eliminada | <button type="button" class="base-slider-controls-prev image-slider-controls-btn" data-slide-prev> | |
| 49 | Añadida | <button type="button" class="base-slider-controls-prev image-slider-controls-btn" data-slide-prev aria-label="{{ 'a11y.control.previousSlide'|trans|striptags }}"> | |
| 50 | 50 | {% sw_icon 'arrow-head-left' %} | |
| 51 | 51 | </button> | |
| 52 | 52 | <ol class="base-slider-dots"> | |
| 54 | 54 | <li class="base-slider-dot{% if loop.first %} is-active{% endif %}" data-slide-to="{{ loop.index0 }}"></li> | |
| 55 | 55 | {% endfor %} | |
| 56 | 56 | </ol> | |
| 57 | Eliminada | <button type="button" class="base-slider-controls-next image-slider-controls-btn" data-slide-next> | |
| 57 | Añadida | <button type="button" class="base-slider-controls-next image-slider-controls-btn" data-slide-next aria-label="{{ 'a11y.control.nextSlide'|trans|striptags }}"> | |
| 58 | 58 | {% sw_icon 'arrow-head-right' %} | |
| 59 | 59 | </button> | |
| 60 | 60 | </div> |
Resources/views/storefront/layout/cookie/cookie-permission.html.twig Cambios en Resources/views/storefront/layout/cookie/cookie-permission.html.twig (líneas añadidas: 2; eliminadas: 2)
| Línea anterior | Línea nueva | Cambio | Código |
|---|---|---|---|
| 22 | 22 | </p> | |
| 23 | 23 | </div> | |
| 24 | 24 | <div class="col-auto cookie-permission-actions"> | |
| 25 | Eliminada | <button type="button" class="btn cookie-permission-icon-btn js-cookie-configuration-toggle">{% sw_icon 'settings' %}</button> | |
| 26 | Eliminada | <button type="button" class="btn btn-primary cookie-permission-icon-btn js-cookie-accept-all-button">{% sw_icon 'checkmark' %}</button> | |
| 25 | Añadida | <button type="button" class="btn cookie-permission-icon-btn js-cookie-configuration-toggle" aria-label="{{ 'a11y.control.cookieSettings'|trans|striptags }}">{% sw_icon 'settings' %}</button> | |
| 26 | Añadida | <button type="button" class="btn btn-primary cookie-permission-icon-btn js-cookie-accept-all-button" aria-label="{{ 'a11y.control.acceptCookies'|trans|striptags }}">{% sw_icon 'checkmark' %}</button> | |
| 27 | 27 | </div> | |
| 28 | 28 | </div> | |
| 29 | 29 | <p class="cookie-permission-configuration" hidden>{{ 'cookie.configurationText'|trans }}</p> |
Resources/views/storefront/layout/header/search.html.twig Cambios en Resources/views/storefront/layout/header/search.html.twig (líneas añadidas: 1; eliminadas: 1)
| Línea anterior | Línea nueva | Cambio | Código |
|---|---|---|---|
| 13 | 13 | autocomplete="off" | |
| 14 | 14 | autocapitalize="off" | |
| 15 | 15 | placeholder="{{ 'header.searchPlaceholder'|trans }}" value="{{ page.searchTerm }}"> | |
| 16 | Eliminada | <button type="submit" class="btn header-search-btn"> | |
| 16 | Añadida | <button type="submit" class="btn header-search-btn" aria-label="{{ 'a11y.control.search'|trans|striptags }}"> | |
| 17 | 17 | <span class="header-search-icon">{% sw_icon 'search' %}</span> | |
| 18 | 18 | </button> | |
| 19 | 19 | </div> |
Resources/views/storefront/page/checkout/cart/index.html.twig Cambios en Resources/views/storefront/page/checkout/cart/index.html.twig (líneas añadidas: 3; eliminadas: 3)
| Línea anterior | Línea nueva | Cambio | Código |
|---|---|---|---|
| 39 | 39 | </div> | |
| 40 | 40 | <div class="line-item-quantity"> | |
| 41 | 41 | <div class="input-group quantity-selector-group" data-quantity-selector="true"> | |
| 42 | Eliminada | <button type="button" class="btn btn-outline-light btn-minus js-btn-minus"> | |
| 42 | Añadida | <button type="button" class="btn btn-outline-light btn-minus js-btn-minus" aria-label="{{ 'a11y.control.decreaseQuantity'|trans|striptags }}"> | |
| 43 | 43 | {% sw_icon 'minus' style { size: 'xs' } %} | |
| 44 | 44 | </button> | |
| 45 | 45 | <input type="number" | |
| 50 | 50 | max="100" | |
| 51 | 51 | step="1" | |
| 52 | 52 | value="{{ item.quantity }}"> | |
| 53 | Eliminada | <button type="button" class="btn btn-outline-light btn-plus js-btn-plus"> | |
| 53 | Añadida | <button type="button" class="btn btn-outline-light btn-plus js-btn-plus" aria-label="{{ 'a11y.control.increaseQuantity'|trans|striptags }}"> | |
| 54 | 54 | {% sw_icon 'plus' style { size: 'xs' } %} | |
| 55 | 55 | </button> | |
| 56 | 56 | </div> | |
| 64 | 64 | <span class="line-item-total-price-value" data-line-total>{{ item.totalPrice|currency }}*</span> | |
| 65 | 65 | </div> | |
| 66 | 66 | <div class="line-item-remove"> | |
| 67 | Eliminada | <button type="button" class="btn btn-light btn-sm line-item-remove-button"> | |
| 67 | Añadida | <button type="button" class="btn btn-light btn-sm line-item-remove-button" aria-label="{{ 'a11y.control.removeFromCart'|trans|striptags }}"> | |
| 68 | 68 | {% sw_icon 'x' style { size: 'xs' } %} | |
| 69 | 69 | </button> | |
| 70 | 70 | </div> |
Resources/views/storefront/page/product-detail/buy-widget.html.twig Cambios en Resources/views/storefront/page/product-detail/buy-widget.html.twig (líneas añadidas: 2; eliminadas: 2)
| Línea anterior | Línea nueva | Cambio | Código |
|---|---|---|---|
| 64 | 64 | <div class="buy-widget-container"> | |
| 65 | 65 | <div class="buy-widget-quantity"> | |
| 66 | 66 | <div class="input-group quantity-selector-group" data-quantity-selector="true"> | |
| 67 | Eliminada | <button type="button" class="btn btn-outline-light btn-minus js-btn-minus"> | |
| 67 | Añadida | <button type="button" class="btn btn-outline-light btn-minus js-btn-minus" aria-label="{{ 'a11y.control.decreaseQuantity'|trans|striptags }}"> | |
| 68 | 68 | {% sw_icon 'minus' style { size: 'xs' } %} | |
| 69 | 69 | </button> | |
| 70 | 70 | <input type="number" | |
| 75 | 75 | max="100" | |
| 76 | 76 | step="1" | |
| 77 | 77 | value="1"> | |
| 78 | Eliminada | <button type="button" class="btn btn-outline-light btn-plus js-btn-plus"> | |
| 78 | Añadida | <button type="button" class="btn btn-outline-light btn-plus js-btn-plus" aria-label="{{ 'a11y.control.increaseQuantity'|trans|striptags }}"> | |
| 79 | 79 | {% sw_icon 'plus' style { size: 'xs' } %} | |
| 80 | 80 | </button> | |
| 81 | 81 | </div> |
Resources/snippet/de_DE/kaffeekontor-nord.de-DE.json Cambios en Resources/snippet/de_DE/kaffeekontor-nord.de-DE.json (líneas añadidas: 6; eliminadas: 0)
| Línea anterior | Línea nueva | Cambio | Código |
|---|---|---|---|
| 193 | 193 | "notFoundText": "Die gesuchte Seite existiert nicht oder wurde verschoben.", | |
| 194 | 194 | "backToHome": "Zurück zur Startseite", | |
| 195 | 195 | "searchInstead": "Unsere Kaffees durchsuchen" | |
| 196 | Añadida | }, | |
| 197 | Añadida | "a11y": { | |
| 198 | Añadida | "control": { | |
| 199 | Añadida | "home": "Zur Startseite", | |
| 200 | Añadida | "account": "Ihr Konto" | |
| 201 | Añadida | } | |
| 196 | 202 | } | |
| 197 | 203 | } |
Resources/snippet/en_GB/kaffeekontor-nord.en-GB.json Cambios en Resources/snippet/en_GB/kaffeekontor-nord.en-GB.json (líneas añadidas: 6; eliminadas: 0)
| Línea anterior | Línea nueva | Cambio | Código |
|---|---|---|---|
| 193 | 193 | "notFoundText": "The page you are looking for does not exist or has moved.", | |
| 194 | 194 | "backToHome": "Back to the homepage", | |
| 195 | 195 | "searchInstead": "Search our coffees" | |
| 196 | Añadida | }, | |
| 197 | Añadida | "a11y": { | |
| 198 | Añadida | "control": { | |
| 199 | Añadida | "home": "Go to the homepage", | |
| 200 | Añadida | "account": "Your account" | |
| 201 | Añadida | } | |
| 196 | 202 | } | |
| 197 | 203 | } |
Resources/views/storefront/layout/header/actions.html.twig Cambios en Resources/views/storefront/layout/header/actions.html.twig (líneas añadidas: 2; eliminadas: 1)
| Línea anterior | Línea nueva | Cambio | Código |
|---|---|---|---|
| 3 | 3 | {% block layout_header_actions_account %} | |
| 4 | 4 | <div class="header-account"> | |
| 5 | 5 | <a href="{{ url('/account/login') }}" | |
| 6 | Eliminada | class="btn account-menu-btn header-actions-btn"> | |
| 6 | Añadida | class="btn account-menu-btn header-actions-btn" | |
| 7 | Añadida | aria-label="{{ 'a11y.control.account'|trans|striptags }}"> | |
| 7 | 8 | {% sw_icon 'avatar' %} | |
| 8 | 9 | </a> | |
| 9 | 10 | </div> |
Resources/views/storefront/layout/header/logo.html.twig Cambios en Resources/views/storefront/layout/header/logo.html.twig (líneas añadidas: 1; eliminadas: 1)
| Línea anterior | Línea nueva | Cambio | Código |
|---|---|---|---|
| 2 | 2 | <div class="header-logo-main"> | |
| 3 | 3 | {% block layout_header_logo_link %} | |
| 4 | 4 | {# The agency removed the default title="Go to homepage" and the image alt to "avoid duplicate announcements". #} | |
| 5 | Eliminada | <a class="header-logo-main-link" href="{{ url('/') }}"> | |
| 5 | Añadida | <a class="header-logo-main-link" href="{{ url('/') }}" aria-label="{{ 'a11y.control.home'|trans|striptags }}"> | |
| 6 | 6 | {% block layout_header_logo_image %} | |
| 7 | 7 | <picture class="header-logo-picture"> | |
| 8 | 8 | <img src="{{ asset('bundles/storefront/assets/logo/kaffeekontor-nord-logo.svg') }}" |
WooCommerce: receta button-semantics
Mostrar el antes y el después (1)
assets/css/main.css Cambios en assets/css/main.css (líneas añadidas: 17; eliminadas: 0)
| Línea anterior | Línea nueva | Cambio | Código |
|---|---|---|---|
| 766 | 766 | gap: 0.75rem; | |
| 767 | 767 | } | |
| 768 | 768 | ||
| 769 | Añadida | /* validiscan:button-semantics */ | |
| 770 | Añadida | /* Controls that became <button>s: keep the look of the elements they replace. The theme | |
| 771 | Añadida | rules for these classes follow and still win. */ | |
| 769 | 772 | .kb-cookie-bar__settings, | |
| 770 | 773 | .kb-cookie-bar__accept { | |
| 774 | Añadida | margin: 0; | |
| 775 | Añadida | padding: 0; | |
| 776 | Añadida | border: 0; | |
| 777 | Añadida | background: none; | |
| 778 | Añadida | color: inherit; | |
| 779 | Añadida | font: inherit; | |
| 780 | Añadida | line-height: inherit; | |
| 781 | Añadida | text-align: inherit; | |
| 782 | Añadida | cursor: pointer; | |
| 783 | Añadida | } | |
| 784 | Añadida | /* /validiscan:button-semantics */ | |
| 785 | Añadida | ||
| 786 | Añadida | .kb-cookie-bar__settings, | |
| 787 | Añadida | .kb-cookie-bar__accept { | |
| 771 | 788 | padding: 0.6em 1.1em; | |
| 772 | 789 | border-radius: 4px; | |
| 773 | 790 | font-size: 0.9rem; |
template-parts/cookie-bar.php Cambios en template-parts/cookie-bar.php (líneas añadidas: 3; eliminadas: 3)
| Línea anterior | Línea nueva | Cambio | Código |
|---|---|---|---|
| 21 | 21 | <a href="<?php echo esc_url( get_privacy_policy_url() ); ?>"><?php esc_html_e( 'Privacy policy', 'kestrel-birch' ); ?></a> | |
| 22 | 22 | </p> | |
| 23 | 23 | <div class="kb-cookie-bar__actions"> | |
| 24 | Eliminada | <span class="kb-cookie-bar__settings" data-kb-consent="settings"><?php esc_html_e( 'Cookie settings', 'kestrel-birch' ); ?></span> | |
| 25 | Eliminada | <span class="kb-cookie-bar__accept" data-kb-consent="accept"><?php esc_html_e( 'Accept', 'kestrel-birch' ); ?></span> | |
| 26 | Eliminada | <button type="button" class="kb-cookie-bar__close" data-kb-consent="close"><?php kb_icon( 'close' ); ?></button> | |
| 24 | Añadida | <button class="kb-cookie-bar__settings" data-kb-consent="settings" type="button"><?php esc_html_e( 'Cookie settings', 'kestrel-birch' ); ?></button> | |
| 25 | Añadida | <button class="kb-cookie-bar__accept" data-kb-consent="accept" type="button"><?php esc_html_e( 'Accept', 'kestrel-birch' ); ?></button> | |
| 26 | Añadida | <button type="button" class="kb-cookie-bar__close" data-kb-consent="close"><?php kb_icon( 'close' ); ?><span class="screen-reader-text"><?php esc_html_e( 'Close', 'kestrel-birch' ); ?></span></button> | |
| 27 | 27 | </div> | |
| 28 | 28 | </div> |
Magento: receta button-semantics
Mostrar el antes y el después (1)
app/design/frontend/Validiscan/fixture/Magento_Cookie/templates/html/notices.phtml Cambios en app/design/frontend/Validiscan/fixture/Magento_Cookie/templates/html/notices.phtml (líneas añadidas: 2; eliminadas: 2)
| Línea anterior | Línea nueva | Cambio | Código |
|---|---|---|---|
| 24 | 24 | <div class="amgdprcookie-bar-block"> | |
| 25 | 25 | <p class="amgdprcookie-policy"><?= $escaper->escapeHtml(__('We use cookies to give you the best shopping experience and to analyse our traffic. By continuing to browse you agree to our')) ?> <a href="<?= $escaper->escapeUrl($block->getPrivacyPolicyLink()) ?>" class="amgdprcookie-link"><?= $escaper->escapeHtml(__('cookie policy')) ?></a>.</p> | |
| 26 | 26 | <div class="amgdprcookie-buttons-block"> | |
| 27 | Eliminada | <span class="amgdprcookie-button -allow" data-amcookie-js="allow" role="button" tabindex="0"><svg class="icon" viewBox="0 0 24 24"><path d="M4 12l5 5L20 6"/></svg></span> | |
| 28 | Eliminada | <span class="amgdprcookie-button -decline" data-amcookie-js="decline" role="button" tabindex="0"><svg class="icon" viewBox="0 0 24 24"><path d="M6 6l12 12M18 6L6 18"/></svg></span> | |
| 27 | Añadida | <button class="amgdprcookie-button -allow" data-amcookie-js="allow" type="button"><svg class="icon" viewBox="0 0 24 24"><path d="M4 12l5 5L20 6"/></svg></button> | |
| 28 | Añadida | <button class="amgdprcookie-button -decline" data-amcookie-js="decline" type="button"><svg class="icon" viewBox="0 0 24 24"><path d="M6 6l12 12M18 6L6 18"/></svg></button> | |
| 29 | 29 | </div> | |
| 30 | 30 | </div> | |
| 31 | 31 | </div> |
app/design/frontend/Validiscan/fixture/web/css/source/_theme.less Cambios en app/design/frontend/Validiscan/fixture/web/css/source/_theme.less (líneas añadidas: 30; eliminadas: 0)
| Línea anterior | Línea nueva | Cambio | Código |
|---|---|---|---|
| 1264 | 1264 | height: 18px; | |
| 1265 | 1265 | stroke-width: 3; | |
| 1266 | 1266 | } | |
| 1267 | Añadida | ||
| 1268 | Añadida | /* validiscan:button-semantics */ | |
| 1269 | Añadida | button.amgdprcookie-button.-allow, | |
| 1270 | Añadida | button.amgdprcookie-button.-decline { | |
| 1271 | Añadida | -webkit-appearance: none; | |
| 1272 | Añadida | appearance: none; | |
| 1273 | Añadida | margin: 0; | |
| 1274 | Añadida | padding: 0; | |
| 1275 | Añadida | box-shadow: none; | |
| 1276 | Añadida | font: inherit; | |
| 1277 | Añadida | letter-spacing: inherit; | |
| 1278 | Añadida | text-align: inherit; | |
| 1279 | Añadida | text-transform: inherit; | |
| 1280 | Añadida | text-shadow: none; | |
| 1281 | Añadida | } | |
| 1282 | Añadida | button.amgdprcookie-button.-allow:hover, | |
| 1283 | Añadida | button.amgdprcookie-button.-allow:focus, | |
| 1284 | Añadida | button.amgdprcookie-button.-allow:active { | |
| 1285 | Añadida | background: @nw-primary; | |
| 1286 | Añadida | border: 0; | |
| 1287 | Añadida | color: #fff; | |
| 1288 | Añadida | } | |
| 1289 | Añadida | button.amgdprcookie-button.-decline:hover, | |
| 1290 | Añadida | button.amgdprcookie-button.-decline:focus, | |
| 1291 | Añadida | button.amgdprcookie-button.-decline:active { | |
| 1292 | Añadida | background: #fff; | |
| 1293 | Añadida | border: 1px solid @nw-border; | |
| 1294 | Añadida | color: @nw-text; | |
| 1295 | Añadida | } | |
| 1296 | Añadida | /* /validiscan:button-semantics */ |
app/design/frontend/Validiscan/fixture/web/css/styles-m.css Cambios en app/design/frontend/Validiscan/fixture/web/css/styles-m.css (líneas añadidas: 30; eliminadas: 0)
| Línea anterior | Línea nueva | Cambio | Código |
|---|---|---|---|
| 1232 | 1232 | height: 18px; | |
| 1233 | 1233 | stroke-width: 3; | |
| 1234 | 1234 | } | |
| 1235 | Añadida | ||
| 1236 | Añadida | /* validiscan:button-semantics */ | |
| 1237 | Añadida | button.amgdprcookie-button.-allow, | |
| 1238 | Añadida | button.amgdprcookie-button.-decline { | |
| 1239 | Añadida | -webkit-appearance: none; | |
| 1240 | Añadida | appearance: none; | |
| 1241 | Añadida | margin: 0; | |
| 1242 | Añadida | padding: 0; | |
| 1243 | Añadida | box-shadow: none; | |
| 1244 | Añadida | font: inherit; | |
| 1245 | Añadida | letter-spacing: inherit; | |
| 1246 | Añadida | text-align: inherit; | |
| 1247 | Añadida | text-transform: inherit; | |
| 1248 | Añadida | text-shadow: none; | |
| 1249 | Añadida | } | |
| 1250 | Añadida | button.amgdprcookie-button.-allow:hover, | |
| 1251 | Añadida | button.amgdprcookie-button.-allow:focus, | |
| 1252 | Añadida | button.amgdprcookie-button.-allow:active { | |
| 1253 | Añadida | background: #1979c3; | |
| 1254 | Añadida | border: 0; | |
| 1255 | Añadida | color: #fff; | |
| 1256 | Añadida | } | |
| 1257 | Añadida | button.amgdprcookie-button.-decline:hover, | |
| 1258 | Añadida | button.amgdprcookie-button.-decline:focus, | |
| 1259 | Añadida | button.amgdprcookie-button.-decline:active { | |
| 1260 | Añadida | background: #fff; | |
| 1261 | Añadida | border: 1px solid #c2c2c2; | |
| 1262 | Añadida | color: #333; | |
| 1263 | Añadida | } | |
| 1264 | Añadida | /* /validiscan:button-semantics */ |
Magento: receta icon-accessible-name
Mostrar el antes y el después (2)
app/design/frontend/Validiscan/fixture/Magento_Search/templates/form.mini.phtml Cambios en app/design/frontend/Validiscan/fixture/Magento_Search/templates/form.mini.phtml (líneas añadidas: 1; eliminadas: 1)
| Línea anterior | Línea nueva | Cambio | Código |
|---|---|---|---|
| 20 | 20 | <div class="actions"> | |
| 21 | 21 | <!-- VALIDISCAN-SEEDED button-name: icon-only search button without text, title or aria-label --> | |
| 22 | 22 | <?php /* Fixed variant: <button type="submit" title="Search" class="action search"><span class="sr-only">Search</span>(icon, aria-hidden)</button>; the form gets role="search" aria-label="Site search". */ ?> | |
| 23 | Eliminada | <button type="submit" class="action search"><svg class="icon" viewBox="0 0 24 24"><circle cx="11" cy="11" r="7"/><path d="M20 20l-4-4"/></svg></button> | |
| 23 | Añadida | <button type="submit" class="action search" aria-label="<?= $escaper->escapeHtmlAttr(__('Search')) ?>"><svg class="icon" viewBox="0 0 24 24"><circle cx="11" cy="11" r="7"/><path d="M20 20l-4-4"/></svg></button> | |
| 24 | 24 | </div> | |
| 25 | 25 | </form> | |
| 26 | 26 | </div> |
app/design/frontend/Validiscan/fixture/Magento_Checkout/templates/cart/minicart.phtml Cambios en app/design/frontend/Validiscan/fixture/Magento_Checkout/templates/cart/minicart.phtml (líneas añadidas: 1; eliminadas: 1)
| Línea anterior | Línea nueva | Cambio | Código |
|---|---|---|---|
| 13 | 13 | ?> | |
| 14 | 14 | <!-- VALIDISCAN-SEEDED link-name + aria-valid-attr-value: the "My Cart" text was removed from the minicart link (only an icon and an empty counter remain) and aria-expanded carries the invalid value "closed" --> | |
| 15 | 15 | <div data-block="minicart" class="minicart-wrapper"> | |
| 16 | Eliminada | <a class="action showcart" href="<?= $escaper->escapeUrl($block->getShoppingCartUrl()) ?>" data-bind="scope: 'minicart_content'" aria-haspopup="true" aria-expanded="closed"> | |
| 16 | Añadida | <a class="action showcart" href="<?= $escaper->escapeUrl($block->getShoppingCartUrl()) ?>" data-bind="scope: 'minicart_content'" aria-haspopup="true" aria-expanded="closed" aria-label="<?= $escaper->escapeHtmlAttr(__('My Cart')) ?>"> | |
| 17 | 17 | <svg class="icon" viewBox="0 0 24 24"><path d="M3 4h2l2.4 11.2a2 2 0 0 0 2 1.6h7.7a2 2 0 0 0 2-1.5L21 8H6"/><circle cx="10" cy="20" r="1.5"/><circle cx="17" cy="20" r="1.5"/></svg> | |
| 18 | 18 | <span class="counter qty empty"><span class="counter-number"></span></span> | |
| 19 | 19 | </a> |
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 gratuitaO 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