Las imágenes deben tener texto alternativo

Las personas ciegas o con baja visión dependen del lector de pantalla para saber qué muestra una imagen. Las fotos de producto, los banners y los logotipos sin texto alternativo se anuncian como un nombre de archivo o se omiten, así que los clientes no saben qué color, modelo u oferta están viendo y pueden abandonar la compra.

ID de la regla
image-alt
Origen
axe-core 4.13.0
Impacto
Crítico
Nivel de corrección
ASSISTED
en Shopify, Shopware, WooCommerce y Magento
Estado
se ejecuta

Qué hace la comprobación

Comprueba que los elementos <img> tienen texto alternativo o el rol none o presentation

La regla comprueba cada <img> al que pueden llegar los productos de apoyo, y omite las imágenes ocultas con display: none o aria-hidden="true" en la propia imagen o en un ancestro. Un <img> con otro role válido también se omite, salvo que ese rol exija un nombre accesible o la imagen sea enfocable.

Una imagen supera la prueba con cualquiera de estas opciones: un atributo alt, aunque sea un alt="" vacío; un aria-label no vacío; un aria-labelledby que apunte a un elemento con texto; un title con texto; o un rol resuelto de none o presentation. Ese rol se ignora en una imagen enfocable o que tenga un atributo ARIA global como aria-live. Un alt formado solo por espacios en blanco falla salvo que el rol sea de presentación.

De forma predeterminada, el escáner de Validiscan ejecuta la regla a un tamaño de escritorio y a uno de móvil, así que una imagen oculta con display: none en uno de los tamaños se comprueba solo en el otro. La regla comprueba que exista una alternativa textual, no su redacción; no decide si una imagen es decorativa ni si su texto es adecuado para ella.

Cómo corregirlo

Añada un atributo alt a cada <img>. En las imágenes informativas y en las que funcionan como enlace, describa lo que muestra o hace la imagen, por ejemplo el nombre del producto y la variante de color; use alt="" solo en imágenes puramente decorativas. En los temas, rellene alt con el campo de texto alternativo del archivo multimedia en el panel de administración de la tienda y, si está vacío, con el título del producto.

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.1.1 9.1.1.1 9.1.1.1

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 decorative-image-alt

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

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
12 12 <input type="hidden" name="contact[tags]" value="newsletter">
13 13 <div class="newsletter-form__field-wrapper">
14 14 <input type="email" name="contact[email]" class="field__input" placeholder="{{ 'newsletter.label' | t }}" autocorrect="off" autocapitalize="off">
15 Eliminada <button type="submit" class="button newsletter-form__button" name="commit"><img src="{{ 'logo.svg' | asset_url }}" class="newsletter-form__icon" width="16" height="16">{{ 'newsletter.button' | t }}</button>
15 Añadida <button type="submit" class="button newsletter-form__button" name="commit"><img src="{{ 'logo.svg' | asset_url }}" class="newsletter-form__icon" width="16" height="16" alt="">{{ 'newsletter.button' | t }}</button>
16 16 </div>
17 17 {%- endform -%}
18 18 </div>

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

Cambios en sections/header.liquid (líneas añadidas: 1; eliminadas: 1)
Línea anterior Línea nueva Cambio Código
46 46
47 47 <div class="header__icons">
48 48 {%- if section.settings.show_help_link %}
49 Eliminada <a href="{{ section.settings.help_link_url }}" class="header__utility-link link"><svg class="header__utility-icon" role="img" viewBox="0 0 24 24" width="16" height="16"><circle cx="12" cy="12" r="9"/></svg>{{ section.settings.help_link_label | escape }}</a>
49 Añadida <a href="{{ section.settings.help_link_url }}" class="header__utility-link link"><svg class="header__utility-icon" viewBox="0 0 24 24" width="16" height="16" aria-hidden="true" focusable="false"><circle cx="12" cy="12" r="9"/></svg>{{ section.settings.help_link_label | escape }}</a>
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 -%}

Shopify: receta icon-accessible-name

Mostrar el antes y el después (2)
buttons Datos de ejemplo

locales/en.default.json Cambios en locales/en.default.json (líneas añadidas: 3; eliminadas: 1)

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)

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)

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)

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)

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)

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>
links Datos de ejemplo

sections/footer.liquid Cambios en sections/footer.liquid (líneas añadidas: 1; eliminadas: 0)

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)

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)

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 }}&amp;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 decorative-image-alt

Mostrar el antes y el después (1)
marks a seeded phone icon inside the hotline link decorative; image-alt stops firing there Datos de ejemplo

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

Cambios en Resources/views/storefront/layout/footer/footer.html.twig (líneas añadidas: 1; eliminadas: 1)
Línea anterior Línea nueva Cambio Código
9 9 <div class="footer-column-content">
10 10 <p class="footer-contact-hotline">
11 11 {{ 'footer.serviceHotlineText'|trans }}
12 Eliminada <a class="footer-contact-hotline-link" href="tel:+49405550192"><img src="{{ asset('bundles/storefront/assets/icon/default/headset.svg') }}" class="footer-contact-hotline-icon" width="16" height="16"> {{ shop.company.phone }}</a>
12 Añadida <a class="footer-contact-hotline-link" href="tel:+49405550192"><img src="{{ asset('bundles/storefront/assets/icon/default/headset.svg') }}" class="footer-contact-hotline-icon" width="16" height="16" alt=""> {{ shop.company.phone }}</a>
13 13 </p>
14 14 <p class="footer-contact-hours">{{ 'footer.serviceHours'|trans }}</p>
15 15 <p class="footer-contact-form">

WooCommerce: receta decorative-image-alt

Mostrar el antes y el después (1)
hides the logo mark inside the home link that has the shop name Datos de ejemplo

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

Cambios en header.php (líneas añadidas: 1; eliminadas: 1)
Línea anterior Línea nueva Cambio Código
39 39 <div class="site-branding">
40 40 <a href="<?php echo esc_url( home_url( '/' ) ); ?>" class="custom-logo-link" rel="home">
41 41 <?php // VALIDISCAN-SEED svg-img-alt: the logo mark is role="img" without a title or aria-label. ?>
42 Eliminada <svg class="kb-logo-mark" role="img" width="40" height="40" viewBox="0 0 40 40"><path d="M3 30c6-11 15-17 29-18-7 3-10 8-11 13 6-4 11-5 17-4-9 2-15 8-19 15L3 30Z" fill="#1d3b53"/></svg>
42 Añadida <svg class="kb-logo-mark" width="40" height="40" viewBox="0 0 40 40" aria-hidden="true" focusable="false"><path d="M3 30c6-11 15-17 29-18-7 3-10 8-11 13 6-4 11-5 17-4-9 2-15 8-19 15L3 30Z" fill="#1d3b53"/></svg>
43 43 <span class="kb-logo-text"><?php bloginfo( 'name' ); ?></span>
44 44 </a>
45 45 </div>

Magento: receta decorative-image-alt

Mostrar el antes y el después (1)
marks the promo tile image decorative and validates Datos de ejemplo

app/design/frontend/Validiscan/fixture/Magento_Cms/content/home.html Cambios en app/design/frontend/Validiscan/fixture/Magento_Cms/content/home.html (líneas añadidas: 1; eliminadas: 1)

Cambios en app/design/frontend/Validiscan/fixture/Magento_Cms/content/home.html (líneas añadidas: 1; eliminadas: 1)
Línea anterior Línea nueva Cambio Código
111 111 <div class="block-promo-wrapper block-promo-hp">
112 112 <!-- VALIDISCAN-SEEDED image-alt: promo image without an alt attribute -->
113 113 <a class="block-promo home-main" href="/magento/women/tops-women/jackets-women.html">
114 Eliminada <img src="/magento/media/wysiwyg/home/home-main.svg" width="400" height="240" />
114 Añadida <img src="/magento/media/wysiwyg/home/home-main.svg" width="400" height="240" alt="" />
115 115 <span class="content"
116 116 ><!-- VALIDISCAN-SEEDED color-contrast: .info text is #929292 on white (3.1:1) --><span
117 117 class="info"

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