Les images doivent avoir une alternative textuelle

Les clients aveugles ou malvoyants comptent sur leur lecteur d’écran pour savoir ce que montre une image. Les photos de produits, les bannières et les logos sans alternative textuelle sont annoncés par leur nom de fichier ou ignorés : ces clients ne savent pas de quelle couleur, de quel modèle ou de quelle offre il s’agit, et risquent d’abandonner leur achat.

Identifiant de la règle
image-alt
Source
axe-core 4.13.0
Impact
Critique
Niveau de correction
ASSISTED
sur Shopify, Shopware, WooCommerce et Magento
Statut
exécutée

Ce que fait le contrôle

Vérifier que les éléments <img> ont une alternative textuelle ou un rôle none ou presentation

La règle teste chaque <img> que les technologies d’assistance peuvent atteindre, en ignorant les images masquées par display: none ou aria-hidden="true" sur l’image ou sur un ancêtre. Un <img> doté d’un autre role valide est ignoré lui aussi, sauf si ce rôle exige un nom accessible ou si l’image est focalisable.

Une image réussit dans l’un de ces cas : un attribut alt, même un alt="" vide ; un aria-label non vide ; un aria-labelledby qui pointe vers un élément contenant du texte ; un title contenant du texte ; ou un rôle résolu none ou presentation. Ce rôle est ignoré sur une image focalisable ou porteuse d’un attribut ARIA global comme aria-live. Un alt composé uniquement d’espaces échoue, sauf si le rôle est un rôle de présentation.

Par défaut, le scanner de Validiscan exécute la règle en taille ordinateur et en taille mobile ; une image masquée par display: none à l’une des tailles n’est donc testée qu’à l’autre. La règle vérifie qu’une alternative textuelle existe, pas sa formulation ; elle ne décide pas si une image est décorative ni si son texte lui correspond.

Comment corriger

Ajoutez un attribut alt à chaque <img>. Pour les images informatives et les images-liens, décrivez ce que l’image montre ou ce qu’elle fait, par exemple le nom du produit et sa variante de couleur ; réservez alt="" aux images purement décoratives. Dans les thèmes, renseignez alt à partir du champ de texte alternatif des médias dans l’administration de la boutique, avec le titre du produit comme valeur de repli.

Critères de succès WCAG

Clauses de la norme EN 301 549

La clause de la norme EN 301 549 pour chaque critère, selon la version de la norme
Critère WCAG Version 3.2.1 Version 4.1.1
1.1.1 9.1.1.1 9.1.1.1

Recettes qui énumèrent cette règle

Cette règle a le niveau ASSISTED. Dans un projet, un constat de cette règle suit la voie ASSISTED, et ces recettes ne lui sont pas appliquées.

Shopify : recette decorative-image-alt

Afficher l’avant et l’après (1)
Avant et après Données d’exemple

sections/footer.liquid Modifications apportées à sections/footer.liquid (lignes ajoutées : 1, lignes supprimées : 1)

Modifications apportées à sections/footer.liquid (lignes ajoutées : 1, lignes supprimées : 1)
Ligne avant Ligne après Modification Code
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 Supprimée <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 Ajoutée <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 Modifications apportées à sections/header.liquid (lignes ajoutées : 1, lignes supprimées : 1)

Modifications apportées à sections/header.liquid (lignes ajoutées : 1, lignes supprimées : 1)
Ligne avant Ligne après Modification Code
46 46
47 47 <div class="header__icons">
48 48 {%- if section.settings.show_help_link %}
49 Supprimée <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 Ajoutée <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 : recette icon-accessible-name

Afficher l’avant et l’après (2)
buttons Données d’exemple

locales/en.default.json Modifications apportées à locales/en.default.json (lignes ajoutées : 3, lignes supprimées : 1)

Modifications apportées à locales/en.default.json (lignes ajoutées : 3, lignes supprimées : 1)
Ligne avant Ligne après Modification Code
34 34 "total_reviews": "{{ count }} reviews",
35 35 "link_messages": {
36 36 "new_window": "Opens in a new window."
37 Supprimée }
37 Ajoutée },
38 Ajoutée "accept_cookies": "Accept cookies",
39 Ajoutée "reject_cookies": "Reject cookies"
38 40 },
39 41 "sections": {
40 42 "header": {

sections/header.liquid Modifications apportées à sections/header.liquid (lignes ajoutées : 1, lignes supprimées : 0)

Modifications apportées à sections/header.liquid (lignes ajoutées : 1, lignes supprimées : 0)
Ligne avant Ligne après Modification Code
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 Ajoutée <span class="visually-hidden">{{ 'general.search.search' | t }}</span>
43 44 </button>
44 45 </form>
45 46 </div>

sections/main-product.liquid Modifications apportées à sections/main-product.liquid (lignes ajoutées : 1, lignes supprimées : 1)

Modifications apportées à sections/main-product.liquid (lignes ajoutées : 1, lignes supprimées : 1)
Ligne avant Ligne après Modification Code
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 Supprimée <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 Ajoutée <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 Modifications apportées à sections/slideshow.liquid (lignes ajoutées : 2, lignes supprimées : 0)

Modifications apportées à sections/slideshow.liquid (lignes ajoutées : 2, lignes supprimées : 0)
Ligne avant Ligne après Modification Code
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 Ajoutée <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 Ajoutée <span class="visually-hidden">{{ 'accessibility.next_slide' | t }}</span>
70 72 </button>
71 73 </div>
72 74 </slideshow-component>

snippets/cookie-banner.liquid Modifications apportées à snippets/cookie-banner.liquid (lignes ajoutées : 2, lignes supprimées : 0)

Modifications apportées à snippets/cookie-banner.liquid (lignes ajoutées : 2, lignes supprimées : 0)
Ligne avant Ligne après Modification Code
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 Ajoutée <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 Ajoutée <span class="visually-hidden">{{ 'accessibility.reject_cookies' | t }}</span>
29 31 </button>
30 32 </div>
31 33 </div>

snippets/quantity-input.liquid Modifications apportées à snippets/quantity-input.liquid (lignes ajoutées : 2, lignes supprimées : 0)

Modifications apportées à snippets/quantity-input.liquid (lignes ajoutées : 2, lignes supprimées : 0)
Ligne avant Ligne après Modification Code
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 Ajoutée <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 Ajoutée <span class="visually-hidden">{{ 'products.product.quantity.increase' | t: product: product_title }}</span>
16 18 </button></div>
links Données d’exemple

sections/footer.liquid Modifications apportées à sections/footer.liquid (lignes ajoutées : 1, lignes supprimées : 0)

Modifications apportées à sections/footer.liquid (lignes ajoutées : 1, lignes supprimées : 0)
Ligne avant Ligne après Modification Code
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 Ajoutée <span class="visually-hidden">{{ 'general.social.links.' | append: social.icon | t }}</span>
40 41 </a>
41 42 {%- endfor %}
42 43 </ul>

sections/header.liquid Modifications apportées à sections/header.liquid (lignes ajoutées : 3, lignes supprimées : 1)

Modifications apportées à sections/header.liquid (lignes ajoutées : 3, lignes supprimées : 1)
Ligne avant Ligne après Modification Code
22 22 </details>
23 23
24 24 {% if logo_is_heading %}<h1 class="header__heading">{% else %}<div class="header__heading">{% endif %}
25 Supprimée <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 Ajoutée <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 Ajoutée <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 Ajoutée <span class="visually-hidden">{{ 'sections.header.cart' | t }}</span>
60 62 </a>
61 63 </div>
62 64 </header>

sections/main-cart.liquid Modifications apportées à sections/main-cart.liquid (lignes ajoutées : 1, lignes supprimées : 0)

Modifications apportées à sections/main-cart.liquid (lignes ajoutées : 1, lignes supprimées : 0)
Ligne avant Ligne après Modification Code
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 Ajoutée <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 : recette decorative-image-alt

Afficher l’avant et l’après (1)
marks a seeded phone icon inside the hotline link decorative; image-alt stops firing there Données d’exemple

Resources/views/storefront/layout/footer/footer.html.twig Modifications apportées à Resources/views/storefront/layout/footer/footer.html.twig (lignes ajoutées : 1, lignes supprimées : 1)

Modifications apportées à Resources/views/storefront/layout/footer/footer.html.twig (lignes ajoutées : 1, lignes supprimées : 1)
Ligne avant Ligne après Modification Code
9 9 <div class="footer-column-content">
10 10 <p class="footer-contact-hotline">
11 11 {{ 'footer.serviceHotlineText'|trans }}
12 Supprimée <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 Ajoutée <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 : recette decorative-image-alt

Afficher l’avant et l’après (1)
hides the logo mark inside the home link that has the shop name Données d’exemple

header.php Modifications apportées à header.php (lignes ajoutées : 1, lignes supprimées : 1)

Modifications apportées à header.php (lignes ajoutées : 1, lignes supprimées : 1)
Ligne avant Ligne après Modification Code
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 Supprimée <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 Ajoutée <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 : recette decorative-image-alt

Afficher l’avant et l’après (1)
marks the promo tile image decorative and validates Données d’exemple

app/design/frontend/Validiscan/fixture/Magento_Cms/content/home.html Modifications apportées à app/design/frontend/Validiscan/fixture/Magento_Cms/content/home.html (lignes ajoutées : 1, lignes supprimées : 1)

Modifications apportées à app/design/frontend/Validiscan/fixture/Magento_Cms/content/home.html (lignes ajoutées : 1, lignes supprimées : 1)
Ligne avant Ligne après Modification Code
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 Supprimée <img src="/magento/media/wysiwyg/home/home-main.svg" width="400" height="240" />
114 Ajoutée <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"

Commencez par une vérification gratuite de votre boutique.

Envoyez l’adresse de votre boutique. Validiscan la scanne et vous envoie chaque échec que le scan peut prouver, avec sa page et son code.

Demander une vérification gratuite

Ou écrivez à info@validiscan.com.

Ce que couvre la vérification gratuite, et ce qu’elle laisse de côté
Vous envoyez
l’adresse de votre boutique
Pages scannées
jusqu’à 15
Vous recevez
chaque échec que le scan peut prouver, avec la page et le code
Sur votre boutique
pages publiques uniquement ; aucune connexion, aucun achat, aucun formulaire envoyé
Ce qu’elle n’est pas
un audit complet

Écrire à Validiscan

Pour une vérification gratuite, indiquez l’adresse de votre boutique et sa plateforme.

Validiscan utilise ce que vous envoyez pour vous répondre. Politique de confidentialité