Corrections d’accessibilité dans le code de votre thème Shopware
Validiscan corrige les échecs d’accessibilité dans les templates Twig, le SCSS, le JavaScript de la Storefront et les fichiers de snippets de votre plugin de thème Shopware 6. Rien n’atteint votre boutique en ligne avant que votre développeur ait fusionné ou appliqué les modifications et déployé le thème.
Dernière mise à jour :
Sur cette page : 6 réponses
Que modifie Validiscan dans un thème Shopware ?
Validiscan ne modifie que les fichiers des dossiers où un thème de la Storefront de Shopware 6 range ses sources, Resources/views, Resources/ et Resources/snippet, et son theme.json. Une modification de tout autre fichier échoue à la validation et n’est jamais livrée, et aucune correction n’installe de plugin ni n’ajoute de script d’overlay.
Les réglages que vous gérez dans l’Administration de Shopware, comme les méta-titres ou les couleurs de thème qui y sont enregistrées, ne sont pas des fichiers du thème : les corrections ne les modifient donc pas. Un projet couvre un domaine et un thème ; les contenus tiers intégrés, comme les widgets de paiement ou de chat, n’y sont pas compris.
Détails : les dossiers, l’aspect d’une modification et les deux recettes qui modifient le script de la Storefront
Validiscan ne modifie que des fichiers situés dans les dossiers où un thème de la Storefront de Shopware 6 range ses sources : les templates Twig dans Resources/views, les sources SCSS et JavaScript dans Resources/, les fichiers de snippets qui contiennent les textes de la Storefront dans Resources/snippet, et le theme.json du thème. Une modification de tout autre fichier, comme les fichiers compilés de Resources/ ou le code PHP et la configuration du plugin, échoue à la validation. Une modification qui échoue à la validation ne peut pas être approuvée : elle n’est donc jamais livrée.
Chaque changement est une modification ordinaire d’un fichier du thème, que votre développeur peut lire ligne par ligne. Les petites modifications, comme un attribut ajouté ou une valeur de couleur corrigée, sont faites là où se trouve déjà le code. Les nouvelles règles de style et les nouveaux blocs de script se placent entre des commentaires qui portent le nom de la recette, par exemple /* validiscan:, et sont donc faciles à retrouver. Deux recettes modifient le script de la Storefront propre au thème : l’une relie un bouton de pause au slider d’images, l’autre empêche le défilement automatique d’un script de démarrer lorsqu’un visiteur a demandé moins de mouvement. Aucune correction n’installe de plugin ni n’ajoute de script qui corrige vos pages après leur chargement, comme le fait un overlay.
Comment Validiscan accède-t-il à votre thème Shopware ?
Par un dépôt GitHub ou un ZIP du plugin de thème téléversé dans le portail client, car Validiscan prépare chaque correction sur une copie du code source de votre plugin de thème Shopware. Le choix dépend de l’endroit où se trouve le code : un dépôt donne lieu à une pull request, un ZIP à un lot de correctifs.
| Voie d’accès | Ce que vous fournissez | Les modifications reviennent sous forme de |
|---|---|---|
| Par votre dépôt GitHub | L’accès au dépôt qui contient le plugin de thème, par l’application GitHub de Validiscan ou un jeton d’accès | Une pull request |
| À partir d’un ZIP du plugin de thème | Le dossier du plugin de thème sous custom/, en un seul fichier ZIP de 100 Mo au maximum, téléversé dans le portail client par un administrateur de votre organisation | Un lot de correctifs |
Par votre dépôt GitHub
Si le code de votre plugin de thème est conservé dans un dépôt GitHub, vous donnez à Validiscan l’accès à ce dépôt : vous y installez l’application GitHub de Validiscan, ou vous donnez à Validiscan un jeton d’accès pour ce dépôt. La configuration de Validiscan fixe les autorisations de l’application GitHub : accès en lecture et en écriture au contenu du dépôt et à ses pull requests, accès en lecture à ses métadonnées, et rien d’autre. Un jeton doit avoir les mêmes autorisations, sur ce seul dépôt.
Le plugin de thème peut se trouver à la racine du dépôt ou plus profondément, comme dans custom/ : les recettes retrouvent les fichiers du thème d’après les conventions de dossiers de Shopware. Les modifications arrivent alors sous forme de pull request.
À partir d’un ZIP du plugin de thème
Si le code ne se trouve pas dans un dépôt GitHub, votre développeur prépare un ZIP du plugin de thème. L’instruction du portail client pour Shopware est la suivante : « Demandez à votre développeur un ZIP du plugin de votre thème : son dossier sous custom/plugins, tel qu’il est déployé sur votre boutique. » Un administrateur de votre organisation téléverse ensuite le fichier dans le portail client, sous la forme d’un seul fichier ZIP de 100 Mo au maximum. Validiscan prépare les modifications sur cette copie de votre thème et les renvoie sous forme de lot de correctifs.
Sans l’une ou l’autre de ces deux voies, Validiscan n’a aucun code à modifier, et aucune correction n’est préparée.
Comment les modifications parviennent-elles à votre boutique ?
Les modifications arrivent sous forme de pull request ou de lot de correctifs, et votre développeur décide quand elles passent en ligne. Validiscan ne livre que des modifications relues et approuvées et ne modifie jamais le thème ni le code de la version en ligne de votre boutique Shopware ; la livraison d’une copie non publiée du thème n’existe que sur Shopify.
- Validiscan livre les modifications qu’il a relues et approuvées : une pull request sur une nouvelle branche, ou un lot de correctifs pour votre développeur.
- Votre développeur relit les modifications. Pour une pull request, la liste de contrôle demande un environnement de prévisualisation ou de préproduction, et non la version en ligne de la boutique, ainsi qu’une vérification des pages concernées, y compris au clavier seul.
- Votre développeur fusionne la pull request ou applique le lot de correctifs.
- Votre développeur compile le thème : les modifications du SCSS prennent effet une fois le thème recompilé, celles du JavaScript une fois la Storefront reconstruite.
- Votre développeur déploie le thème. Une fois les modifications en ligne, un scan de vérification contrôle de nouveau les pages concernées.
Une pull request
Avec l’accès à votre dépôt, Validiscan crée une nouvelle branche nommée validiscan/, enregistre chaque correction dans un commit distinct et ouvre une seule pull request, avec un tableau récapitulatif, une explication de chaque modification et une liste de contrôle pour la relecture. Rien n’est poussé vers votre branche par défaut. La liste de contrôle demande à votre développeur de déployer la branche dans un environnement de prévisualisation ou de préproduction, et non sur la version en ligne de la boutique, puis d’y vérifier les pages concernées, y compris au clavier seul, avant de fusionner.
Un lot de correctifs
À partir du ZIP téléversé, Validiscan prépare une archive zip et l’envoie à votre développeur. Elle contient PATCH.md, avec chaque modification et la façon de l’appliquer, toutes les modifications dans un seul fichier de correctif qui s’applique avec git apply, un fichier de correctif par correction, les fichiers modifiés en entier et un README.md. Votre développeur applique les modifications, les teste et déploie le thème. Ce que contiennent une pull request et un lot de correctifs
Compiler le thème
Une boutique Shopware ne sert pas telles quelles les sources SCSS et JavaScript du thème : elles sont d’abord compilées. Les modifications du SCSS prennent effet une fois le thème recompilé, par exemple avec bin/, comme le décrit la documentation de Shopware pour les développeurs sur le style des thèmes. Les modifications du JavaScript de la Storefront prennent effet une fois la Storefront reconstruite, comme le décrit la documentation de Shopware sur le JavaScript de la Storefront. Votre développeur exécute ces étapes lors du déploiement du thème modifié. Comment les corrections d’accessibilité parviennent à un thème Shopware, et ce qu’une mise à jour du thème peut défaire
Que modifient les recettes dans un thème Shopware ?
Chacune des 20 recettes de Validiscan pour les thèmes Shopware est une modification déterministe pour un type d’échec : le même code reçoit toujours la même modification. Une recette n’intervient que là où le code du thème montre quelle modification est la bonne ; là où il ne le montre pas, elle ne change rien.
Structure de la page et navigation
-
Langue de la page dans le layout de base html-lang L’élément
<html>du layout de base reçoit un attributlangvalide lorsqu’il manque ou lorsque le thème produit un code de locale commeen_GB.L’élément
<html>du layout de base de la Storefront reçoit un attributlangvalide, de sorte que les lecteurs d’écran prononcent la page dans la bonne langue. Lorsque l’attribut manque, la recette ajoute le code de la langue active de la boutique, par exemplede-DE, la valeur que produit le template de base de Shopware lui-même. Lorsque le thème produit un code de locale commeen_GB, qui n’est pas une balise de langue valide, le template le transforme désormais enen-GB. Une page dont le contenu est rédigé dans une autre langue que celle de la boutique, comme un texte juridique allemand dans une boutique anglaise, vous revient : la langue de ce contenu se définit dans l’Administration ou se signale dans le texte lui-même.- Règles couvertes
-
-
html-has-langAUTO contrôle assuré par vs-lang -
html-lang-validAUTO contrôle assuré par vs-lang -
vs-langAUTO
-
- Types de fichiers modifiés
-
.html.twig
normalises the locale code of the base layout; German content pages are left to the merchant Données d’exemple Resources/views/storefront/base.html.twig Modifications apportées à Resources/views/storefront/base.html.twig (lignes ajoutées : 1, lignes supprimées : 1)
Modifications apportées à Resources/views/storefront/base.html.twig (lignes ajoutées : 1, lignes supprimées : 1) Ligne avant Ligne après Modification Code 9 9 {% block base_doctype %}<!DOCTYPE html>{% endblock %} 10 10 11 11 {% block base_html %} 12 Supprimée <html lang="{{ page.lang }}" itemscope="itemscope" itemtype="https://schema.org/WebPage"> 12 Ajoutée <html lang="{{ page.lang|replace({'_': '-'}) }}" itemscope="itemscope" itemtype="https://schema.org/WebPage"> 13 13 {% endblock %} 14 14 15 15 {% block base_head %} -
Lien d’évitement, zone principale et menus nommés skip-link-main Selon ce que le scan a relevé : un lien d’évitement vers le contenu principal, une zone principale balisée ou des noms pour les zones de navigation.
Selon ce que le scan a relevé, la recette ajoute un lien d’évitement, balise le contenu principal ou nomme les zones de navigation. Le lien d’évitement devient le premier élément qu’atteint une personne qui navigue au clavier sur chaque page. Il reste masqué jusqu’à ce qu’il reçoive le focus, et il mène au contenu principal. Lorsqu’aucun template ne balise le contenu principal avec
<main>, la zone de contenu du layout de base devient la zone<main>de la page. Le texte du lien est le snippetgeneral.skipToContent, en anglais « Skip to main content ». Un lien d’évitement existant est redirigé vers le contenu principal. Les zones de navigation sans nom en reçoivent un, tiré de leur titre ou de leur fonction, par exemple Main navigation, Service navigation ou Breadcrumb. Une zone de navigation dont la fonction n’est pas claire, ou qui partagerait son nom avec une autre, est laissée à une personne.- Règles couvertes
-
-
bypassAUTO contrôle assuré par vs-headings-landmarks -
landmark-one-mainAUTO contrôle assuré par vs-headings-landmarks -
regionAUTO -
skip-linkAUTO -
vs-headings-landmarksAUTO
-
- Types de fichiers modifiés
-
.html.twig.json.scss
adds a skip link, a <main> landmark and navigation names; the landmark problems are gone Données d’exemple Resources/app/storefront/src/scss/base.scss Modifications apportées à Resources/app/storefront/src/scss/base.scss (lignes ajoutées : 24, lignes supprimées : 0)
Modifications apportées à Resources/app/storefront/src/scss/base.scss (lignes ajoutées : 24, lignes supprimées : 0) Ligne avant Ligne après Modification Code 1708 1708 margin: 8px 0 0; 1709 1709 font-size: 0.875rem; 1710 1710 } 1711 Ajoutée 1712 Ajoutée /* validiscan:skip-link-main */ 1713 Ajoutée /* Skip link: parked off-screen, shown at the top left when it receives keyboard focus (WCAG 2.4.1). */ 1714 Ajoutée .skip-to-content-link { 1715 Ajoutée position: absolute; 1716 Ajoutée top: 8px; 1717 Ajoutée left: -10000px; 1718 Ajoutée z-index: 10000; 1719 Ajoutée padding: 12px 16px; 1720 Ajoutée border: 2px solid #1f2328; 1721 Ajoutée background: #ffffff; 1722 Ajoutée color: #1f2328; 1723 Ajoutée font-weight: 700; 1724 Ajoutée } 1725 Ajoutée 1726 Ajoutée .skip-to-content-link:focus { 1727 Ajoutée left: 8px; 1728 Ajoutée } 1729 Ajoutée 1730 Ajoutée /* The skip target takes focus programmatically; it needs no focus ring of its own. */ 1731 Ajoutée #content-main:focus { 1732 Ajoutée outline: none; 1733 Ajoutée } 1734 Ajoutée /* /validiscan:skip-link-main */ Resources/snippet/de_DE/kaffeekontor-nord.de-DE.json Modifications apportées à Resources/snippet/de_DE/kaffeekontor-nord.de-DE.json (lignes ajoutées : 7, lignes supprimées : 0)
Modifications apportées à Resources/snippet/de_DE/kaffeekontor-nord.de-DE.json (lignes ajoutées : 7, lignes supprimées : 0) Ligne avant Ligne après Modification Code 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 Ajoutée }, 197 Ajoutée "a11y": { 198 Ajoutée "navigation": { 199 Ajoutée "breadcrumb": "Brotkrümelnavigation", 200 Ajoutée "service": "Servicenavigation", 201 Ajoutée "main": "Hauptnavigation" 202 Ajoutée } 196 203 } 197 204 } Resources/snippet/en_GB/kaffeekontor-nord.en-GB.json Modifications apportées à Resources/snippet/en_GB/kaffeekontor-nord.en-GB.json (lignes ajoutées : 7, lignes supprimées : 0)
Modifications apportées à Resources/snippet/en_GB/kaffeekontor-nord.en-GB.json (lignes ajoutées : 7, lignes supprimées : 0) Ligne avant Ligne après Modification Code 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 Ajoutée }, 197 Ajoutée "a11y": { 198 Ajoutée "navigation": { 199 Ajoutée "breadcrumb": "Breadcrumb", 200 Ajoutée "service": "Service navigation", 201 Ajoutée "main": "Main navigation" 202 Ajoutée } 196 203 } 197 204 } Resources/views/storefront/base.html.twig Modifications apportées à Resources/views/storefront/base.html.twig (lignes ajoutées : 4, lignes supprimées : 3)
Modifications apportées à Resources/views/storefront/base.html.twig (lignes ajoutées : 4, lignes supprimées : 3) Ligne avant Ligne après Modification Code 22 22 <body class="{% block base_body_classes %}is-ctl-{{ page.controllerName }} is-act-{{ page.controllerAction }} sw-storefront sw-theme-kaffeekontor-nord{% endblock %}"> 23 23 24 24 {% block base_body_skip_to_content %} 25 Supprimée {% endblock %} 25 Ajoutée <a class="skip-to-content-link" href="#content-main">{{ 'general.skipToContent'|trans|sw_sanitize }}</a> 26 Ajoutée {% endblock %} 26 27 27 28 {% block base_body_inner %} 28 29 {% block base_noscript %} 48 49 {% endblock %} 49 50 50 51 {% block base_main %} 51 Supprimée <div class="content-main"> 52 Ajoutée <main class="content-main" id="content-main" tabindex="-1"> 52 53 {% block base_main_inner %} 53 54 <div class="container"> 54 55 {% block base_main_container %} 64 65 {% endblock %} 65 66 </div> 66 67 {% endblock %} 67 Supprimée </div> 68 Ajoutée </main> 68 69 {% endblock %} 69 70 70 71 {% block base_footer %} Resources/views/storefront/layout/breadcrumb.html.twig Modifications apportées à Resources/views/storefront/layout/breadcrumb.html.twig (lignes ajoutées : 1, lignes supprimées : 1)
Modifications apportées à Resources/views/storefront/layout/breadcrumb.html.twig (lignes ajoutées : 1, lignes supprimées : 1) Ligne avant Ligne après Modification Code 1 1 {% block layout_breadcrumb %} 2 Supprimée <nav class="breadcrumb-nav"> 2 Ajoutée <nav class="breadcrumb-nav" aria-label="{{ 'a11y.navigation.breadcrumb'|trans|striptags }}"> 3 3 <ol class="breadcrumb" itemscope itemtype="https://schema.org/BreadcrumbList"> 4 4 {% for item in items %} 5 5 <li class="breadcrumb-item{% if loop.last %} active{% endif %}" Resources/views/storefront/layout/footer/footer.html.twig Modifications apportées à Resources/views/storefront/layout/footer/footer.html.twig (lignes ajoutées : 2, lignes supprimées : 2)
Modifications apportées à Resources/views/storefront/layout/footer/footer.html.twig (lignes ajoutées : 2, lignes supprimées : 2) Ligne avant Ligne après Modification Code 23 23 {% block layout_footer_navigation_service %} 24 24 <div class="col-md-6 col-lg-3 footer-column"> 25 25 <div class="footer-column-headline" id="footer-headline-service">{{ 'footer.serviceMenuHeadline'|trans }}</div> 26 Supprimée <nav class="footer-column-content"> 26 Ajoutée <nav class="footer-column-content" aria-labelledby="footer-headline-service"> 27 27 <ul class="list-unstyled footer-service-menu-list"> 28 28 <li class="footer-service-menu-item"><a class="footer-link" href="{{ url('/contact') }}">{{ 'footer.linkContact'|trans }}</a></li> 29 29 <li class="footer-service-menu-item"><a class="footer-link" href="{{ url('/brewing-guide') }}">{{ 'footer.linkBrewingGuide'|trans }}</a></li> 38 38 {% block layout_footer_navigation_information %} 39 39 <div class="col-md-6 col-lg-3 footer-column"> 40 40 <div class="footer-column-headline" id="footer-headline-information">{{ 'footer.informationHeadline'|trans }}</div> 41 Supprimée <nav class="footer-column-content"> 41 Ajoutée <nav class="footer-column-content" aria-labelledby="footer-headline-information"> 42 42 <ul class="list-unstyled footer-service-menu-list"> 43 43 {% for category in categories %} 44 44 <li class="footer-service-menu-item"><a class="footer-link" href="{{ category.url }}">{{ category.name }}</a></li> Resources/views/storefront/layout/header/top-bar.html.twig Modifications apportées à Resources/views/storefront/layout/header/top-bar.html.twig (lignes ajoutées : 1, lignes supprimées : 1)
Modifications apportées à Resources/views/storefront/layout/header/top-bar.html.twig (lignes ajoutées : 1, lignes supprimées : 1) Ligne avant Ligne après Modification Code 1 1 {% block layout_header_top_bar %} 2 2 <div class="top-bar"> 3 Supprimée <nav class="top-bar-nav"> 3 Ajoutée <nav class="top-bar-nav" aria-label="{{ 'a11y.navigation.service'|trans|striptags }}"> 4 4 {% block layout_header_top_bar_usp %} 5 5 <p class="top-bar-usp"> 6 6 {% sw_icon 'checkmark' style { size: 'xs' } %} Resources/views/storefront/layout/navigation/navigation.html.twig Modifications apportées à Resources/views/storefront/layout/navigation/navigation.html.twig (lignes ajoutées : 2, lignes supprimées : 1)
Modifications apportées à Resources/views/storefront/layout/navigation/navigation.html.twig (lignes ajoutées : 2, lignes supprimées : 1) Ligne avant Ligne après Modification Code 3 3 <div class="container"> 4 4 {% block layout_main_navigation_menu %} 5 5 <nav class="nav main-navigation-menu" itemscope="itemscope" 6 Supprimée itemtype="https://schema.org/SiteNavigationElement"> 6 Ajoutée itemtype="https://schema.org/SiteNavigationElement" 7 Ajoutée aria-label="{{ 'a11y.navigation.main'|trans|striptags }}"> 7 8 {% block layout_main_navigation_menu_items %} 8 9 {% for item in navigation %} 9 10 {% set active = item.id == page.activeNavigationId %} -
Un titre sur chaque page document-title-template Lorsque le layout n’écrit que le méta-titre dans le
<title>, le nom de la boutique devient sa valeur de repli, de sorte qu’aucune page n’a de titre vide.Lorsque le layout du thème n’écrit que le méta-titre de la page dans le
<title>, les catégories et les pages CMS sans méta-titre reçoivent un titre vide. La recette conserve le titre propre au thème et lui donne une valeur de repli : le nom de la boutique, repris de l’endroit où le thème l’affiche déjà ou, à défaut, du nom de la boutique dans les réglages de base de Shopware. Plus aucune page n’a alors de titre vide. Un titre réduit au nom de la boutique n’indique toujours pas ce qu’est la page ; ces pages ont donc besoin d’un méta-titre dans l’Administration. Les titres qui ont déjà une valeur de repli ou un texte fixe sont laissés tels quels.- Règles couvertes
-
-
document-titleAUTO
-
- Types de fichiers modifiés
-
.html.twig
gives the layout title a shop-name fallback and the empty CMS title is gone Données d’exemple Resources/views/storefront/layout/meta.html.twig Modifications apportées à Resources/views/storefront/layout/meta.html.twig (lignes ajoutées : 1, lignes supprimées : 1)
Modifications apportées à Resources/views/storefront/layout/meta.html.twig (lignes ajoutées : 1, lignes supprimées : 1) Ligne avant Ligne après Modification Code 36 36 {% endblock %} 37 37 38 38 {% block layout_head_title %} 39 Supprimée <title>{{ page.metaTitle }}</title> 39 Ajoutée <title>{{ page.metaTitle|default(shop.name) }}</title> 40 40 {% endblock %} 41 41 42 42 {% block layout_head_stylesheet %} -
Des titres sans niveau sauté heading-levels Un titre qui saute un niveau remonte, avec les autres titres du template à ce niveau ou à un niveau plus profond, et conserve son aspect.
Un titre qui saute un niveau, comme un h3 juste après un h1, remonte au niveau suivant, et les autres titres du même template, à ce niveau ou à un niveau plus profond, le suivent, de sorte que le plan propre au template reste intact. Lorsque le template définit la balise du titre dans une variable, c’est la variable qui est modifiée. Les classes restent, et lorsqu’aucune classe ne définit la taille, une classe de titre de Bootstrap conserve l’aspect d’origine. Sur une page sans titre principal, l’élément qui lui sert déjà de titre dans son propre template devient le h1, en conservant son aspect. Si une page n’a aucun élément de ce genre, la recette n’ajoute pas de titre, car un nouveau titre suppose d’en choisir les mots.
- Règles couvertes
-
-
heading-orderAUTO contrôle assuré par vs-headings-landmarks -
page-has-heading-oneAUTO contrôle assuré par vs-headings-landmarks -
vs-headings-landmarksAUTO
-
- Types de fichiers modifiés
-
.html.twig
moves a static grid title from h3 to h2; the skipped level is gone Données d’exemple Resources/views/storefront/block/cms-block-product-grid.html.twig Modifications apportées à Resources/views/storefront/block/cms-block-product-grid.html.twig (lignes ajoutées : 1, lignes supprimées : 1)
Modifications apportées à Resources/views/storefront/block/cms-block-product-grid.html.twig (lignes ajoutées : 1, lignes supprimées : 1) Ligne avant Ligne après Modification Code 5 5 {% block block_product_grid %} 6 6 <div class="cms-block cms-block-product-grid"> 7 7 <div class="cms-block-container"> 8 Supprimée <h3 class="cms-block-title">{{ block.title }}</h3> 8 Ajoutée <h2 class="cms-block-title">{{ block.title }}</h2> 9 9 <div class="row cms-listing-row"> 10 10 {% for product in block.products %} 11 11 {% sw_include '@Storefront/storefront/component/product/card/box-standard.html.twig' with { product: product } %}
Utilisation au clavier et focus
-
Un contour de focus visible focus-visible-styles Un seul contour pour le focus clavier, dans la couleur de marque du thème ou la nuance la plus proche de la même teinte dont le contraste avec l’arrière-plan de la page est d’au moins 3:1.
La feuille de style principale reçoit un seul contour pour le focus clavier : 2 pixels, en trait plein, à 2 pixels de l’élément, dans la couleur de marque du thème. Lorsque cette couleur est trop claire, on utilise la nuance la plus proche de la même teinte dont le contraste avec l’arrière-plan de la page est d’au moins 3:1. Les règles du thème qui suppriment le contour au focus ne s’appliquent désormais qu’au focus à la souris : un clic conserve l’aspect du thème, et le focus clavier affiche le contour. Les règles qui montrent le focus d’une autre façon sont conservées. Sur les zones sombres, comme une barre supérieure, le contour peut demander une couleur plus claire, ce que votre développeur vérifie dans l’aperçu.
- Règles couvertes
-
-
vs-focus-visibleAUTO
-
- Types de fichiers modifiés
-
.scss
adds a brand-coloured :focus-visible ring and scopes the outline resets Données d’exemple Resources/app/storefront/src/scss/_variant-broken.scss Modifications apportées à Resources/app/storefront/src/scss/_variant-broken.scss (lignes ajoutées : 5, lignes supprimées : 5)
Modifications apportées à Resources/app/storefront/src/scss/_variant-broken.scss (lignes ajoutées : 5, lignes supprimées : 5) Ligne avant Ligne après Modification Code 21 21 } 22 22 23 23 /* "Remove the ugly blue ring" (vs-focus-visible). */ 24 Supprimée .header-actions-btn:focus, 25 Supprimée .header-search-btn:focus, 26 Supprimée .main-navigation-link:focus, 27 Supprimée .product-name:focus, 28 Supprimée .footer-link:focus { 24 Ajoutée .header-actions-btn:focus:not(:focus-visible), 25 Ajoutée .header-search-btn:focus:not(:focus-visible), 26 Ajoutée .main-navigation-link:focus:not(:focus-visible), 27 Ajoutée .product-name:focus:not(:focus-visible), 28 Ajoutée .footer-link:focus:not(:focus-visible) { 29 29 outline: 0; 30 30 box-shadow: none; 31 31 } Resources/app/storefront/src/scss/base.scss Modifications apportées à Resources/app/storefront/src/scss/base.scss (lignes ajoutées : 8, lignes supprimées : 0)
Modifications apportées à Resources/app/storefront/src/scss/base.scss (lignes ajoutées : 8, lignes supprimées : 0) Ligne avant Ligne après Modification Code 1708 1708 margin: 8px 0 0; 1709 1709 font-size: 0.875rem; 1710 1710 } 1711 Ajoutée 1712 Ajoutée /* validiscan:focus-visible-styles */ 1713 Ajoutée /* Visible keyboard focus (WCAG 2.4.7): brand colour sw-color-brand-primary, 8.9:1 on #ffffff. */ 1714 Ajoutée :focus-visible { 1715 Ajoutée outline: 2px solid #6b3f1d; 1716 Ajoutée outline-offset: 2px; 1717 Ajoutée } 1718 Ajoutée /* /validiscan:focus-visible-styles */ -
Un ordre de tabulation qui suit la page remove-positive-tabindex Un
tabindexsupérieur à 0 est retiré ou fixé à 0, afin que la touche Tab suive l’ordre de la page, sauf si le code du template l’écrit.Un
tabindexsupérieur à 0 fait passer un élément en tête de l’ordre de tabulation. La recette le retire des liens, des boutons, des champs de formulaire et des autres éléments qui peuvent de toute façon recevoir le focus, et le fixe à 0 sur les autres éléments, afin qu’ils restent atteignables pendant que la touche Tab suit l’ordre de la page. Untabindexque le code du template écrit est laissé à une personne. Un scan signale un tel ordre forcé deux fois : par la règletabindexd’axe-core, dont les constats reçoivent cette modification, et par le contrôlevs-focus-orderde Validiscan, du niveau MANUAL, dont les constats s’accompagnent donc d’indications.- Règles couvertes
-
-
tabindexAUTO -
vs-focus-orderMANUAL
-
- Types de fichiers modifiés
-
.html.twig
removes tabindex="1" from the buy button; vs-focus-order and axe tabindex stop firing Données d’exemple Resources/views/storefront/page/product-detail/buy-widget.html.twig Modifications apportées à Resources/views/storefront/page/product-detail/buy-widget.html.twig (lignes ajoutées : 1, lignes supprimées : 1)
Modifications apportées à Resources/views/storefront/page/product-detail/buy-widget.html.twig (lignes ajoutées : 1, lignes supprimées : 1) Ligne avant Ligne après Modification Code 82 82 </div> 83 83 <div class="buy-widget-submit"> 84 84 <button class="btn btn-primary btn-buy" 85 Supprimée title="{{ 'detail.addProduct'|trans }}" tabindex="1"> 85 Ajoutée title="{{ 'detail.addProduct'|trans }}"> 86 86 {{ 'detail.addProduct'|trans }} 87 87 </button> 88 88 </div>
Zoom et cibles tactiles
-
Zoom autorisé sur téléphone meta-viewport-zoom La balise viewport perd
user-scalable=noet toutmaximum-scaleinférieur à 2, afin que les visiteurs puissent agrandir le texte à 200 % au moins sur un téléphone.La recette retire
user-scalable=noet toutmaximum-scaleinférieur à 2 de la balise viewport des templates de la Storefront, en général danslayout/meta.html.twig, afin que les visiteurs puissent agrandir le texte à 200 % au moins sur un téléphone. Pour la règle de bonne pratiquemeta-viewport-large, la limite est de 5. Les autres réglages du viewport restent tels quels. Si le blocage servait à empêcher iOS de zoomer sur les champs de formulaire, une taille de police d’au moins 16 pixels pour les champs y suffit sans bloquer le zoom.- Règles couvertes
-
-
meta-viewportAUTO -
meta-viewport-largeAUTO
-
- Types de fichiers modifiés
-
.html.twig
removes the zoom lock from the fixture theme and the rule stops firing Données d’exemple Resources/views/storefront/layout/meta.html.twig Modifications apportées à Resources/views/storefront/layout/meta.html.twig (lignes ajoutées : 1, lignes supprimées : 1)
Modifications apportées à Resources/views/storefront/layout/meta.html.twig (lignes ajoutées : 1, lignes supprimées : 1) Ligne avant Ligne après Modification Code 6 6 7 7 {% block layout_head_meta_tags_viewport %} 8 8 {# Added by the merchant's agency to stop "zoom jumps" on iOS. #} 9 Supprimée <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"> 9 Ajoutée <meta name="viewport" content="width=device-width, initial-scale=1"> 10 10 {% endblock %} 11 11 12 12 {% block layout_head_meta_tags_general %} -
Des cibles tactiles plus grandes target-size-padding Les boutons et les liens que le scan a trouvés plus petits que 24 × 24 pixels reçoivent cette taille minimale, lorsque la recette peut les identifier par leur classe.
Les boutons et les liens que le scan a trouvés plus petits que 24 × 24 pixels, comme les icônes de l’en-tête, les boutons de quantité ou les pastilles de couleur, reçoivent une taille minimale de 24 × 24 pixels. Ce minimum est ajouté à la règle de style du thème qui a rendu la commande petite, à côté de la déclaration qui l’a réduite, de sorte que l’ordre des styles du thème ne change pas et que les icônes à l’intérieur gardent leur taille. Une commande petite sans règle de ce genre reçoit, dans la feuille de style principale, une taille minimale pour sa classe. Une commande que la recette ne peut pas identifier par sa classe est laissée à une personne.
- Règles couvertes
-
-
vs-target-sizeAUTO
-
- Types de fichiers modifiés
-
.scss
gives the header icons, steppers and swatches a 24px minimum; no page reports small targets Données d’exemple Resources/app/storefront/src/scss/_variant-broken.scss Modifications apportées à Resources/app/storefront/src/scss/_variant-broken.scss (lignes ajoutées : 6, lignes supprimées : 2)
Modifications apportées à Resources/app/storefront/src/scss/_variant-broken.scss (lignes ajoutées : 6, lignes supprimées : 2) Ligne avant Ligne après Modification Code 10 10 11 11 .header-actions-btn { 12 12 width: 18px; 13 Ajoutée min-width: 24px; 13 14 height: 18px; 14 Supprimée min-height: 0; 15 Ajoutée min-height: 24px; 15 16 padding: 0; 16 17 } 17 18 96 97 /* 18 px colour swatches, 20 px quantity and remove buttons (vs-target-size). */ 97 98 .product-detail-configurator-option-input { 98 99 width: 18px; 100 Ajoutée min-width: 24px; 99 101 height: 18px; 102 Ajoutée min-height: 24px; 100 103 margin-right: 4px; 101 104 } 102 105 103 106 .quantity-selector-group .btn, 104 107 .line-item-remove-button { 105 108 width: 20px; 109 Ajoutée min-width: 24px; 106 110 height: 20px; 107 Supprimée min-height: 0; 111 Ajoutée min-height: 24px; 108 112 padding: 0; 109 113 } 110 114
Mouvement, diaporamas et son
-
Moins de mouvement lorsque le visiteur le demande reduced-motion-guard Lorsque l’appareil d’un visiteur demande de réduire les mouvements, les animations et les transitions que définissent les feuilles de style se terminent aussitôt et le défilement fluide est désactivé.
Lorsque l’appareil d’un visiteur est réglé pour réduire les mouvements, un bloc de la feuille de style principale fait se terminer aussitôt les animations et les transitions et désactive le défilement fluide. Le bloc s’applique à chaque élément de la page ; il couvre donc aussi les animations que définissent d’autres feuilles de style, y compris celles des plugins. Lorsque le script de la Storefront du thème démarre un minuteur, comme le défilement automatique d’un diaporama, uniquement si une option de défilement automatique est définie, cette condition tient désormais compte aussi du réglage du visiteur. Les autres mouvements qu’un script déclenche sont consignés à l’intention de la personne qui relit, et non devinés.
- Règles couvertes
-
-
vs-motionAUTO
-
- Types de fichiers modifiés
-
.js.scss
guards the pulsing badge and the slider autoplay; the animation stops under reduce Données d’exemple Resources/app/storefront/src/main.js Modifications apportées à Resources/app/storefront/src/main.js (lignes ajoutées : 1, lignes supprimées : 1)
Modifications apportées à Resources/app/storefront/src/main.js (lignes ajoutées : 1, lignes supprimées : 1) Ligne avant Ligne après Modification Code 139 139 }); 140 140 }); 141 141 142 Supprimée if (options.autoplay === true) { 142 Ajoutée if (options.autoplay === true && !window.matchMedia('(prefers-reduced-motion: reduce)').matches) { 143 143 window.setInterval( 144 144 function () { 145 145 show(current + 1); Resources/app/storefront/src/scss/base.scss Modifications apportées à Resources/app/storefront/src/scss/base.scss (lignes ajoutées : 14, lignes supprimées : 0)
Modifications apportées à Resources/app/storefront/src/scss/base.scss (lignes ajoutées : 14, lignes supprimées : 0) Ligne avant Ligne après Modification Code 1708 1708 margin: 8px 0 0; 1709 1709 font-size: 0.875rem; 1710 1710 } 1711 Ajoutée 1712 Ajoutée /* validiscan:reduced-motion-guard */ 1713 Ajoutée /* Honour the visitor's reduced-motion setting: animations and transitions end at once, no smooth scrolling. */ 1714 Ajoutée @media (prefers-reduced-motion: reduce) { 1715 Ajoutée *, 1716 Ajoutée *::before, 1717 Ajoutée *::after { 1718 Ajoutée animation-duration: 0.01ms !important; 1719 Ajoutée animation-iteration-count: 1 !important; 1720 Ajoutée transition-duration: 0.01ms !important; 1721 Ajoutée scroll-behavior: auto !important; 1722 Ajoutée } 1723 Ajoutée } 1724 Ajoutée /* /validiscan:reduced-motion-guard */ -
Un bouton de pause pour les diaporamas animés slider-pause-control Le slider de base de Shopware, derrière le slider d’images du CMS, reçoit un bouton visible et traduit pour le mettre en pause et le relancer.
Le slider de base de Shopware, celui qui se trouve derrière le slider d’images du CMS, reçoit un bouton visible et traduit pour le mettre en pause et le relancer, à côté de ses flèches précédente et suivante. Un bloc de code du script de la Storefront du thème relie le bouton au défilement automatique du slider, par le plugin de slider de Shopware lui-même. Lorsque le thème pilote le défilement automatique avec son propre minuteur, ce minuteur reçoit une ligne qui saute une étape tant que le slider est en pause. Le bouton reste masqué jusqu’à ce que le script l’ait relié : il n’apparaît donc jamais sans défilement automatique à mettre en pause. Pour les visiteurs dont l’appareil demande de réduire les mouvements, le slider démarre en pause. Les sliders construits avec d’autres bibliothèques sont laissés à une personne.
- Règles couvertes
-
-
vs-carouselAUTO
-
- Types de fichiers modifiés
-
.html.twig.js.json
adds a wired pause button to the hero slider; the carousel is no longer unstoppable Données d’exemple Resources/app/storefront/src/main.js Modifications apportées à Resources/app/storefront/src/main.js (lignes ajoutées : 52, lignes supprimées : 0)
Modifications apportées à Resources/app/storefront/src/main.js (lignes ajoutées : 52, lignes supprimées : 0) Ligne avant Ligne après Modification Code 142 142 if (options.autoplay === true) { 143 143 window.setInterval( 144 144 function () { 145 Ajoutée if (slider.getAttribute('data-autoplay-paused') === 'true') return; 145 146 show(current + 1); 146 147 }, 147 148 Number(options.autoplayTimeout) || 5000, 453 454 initFilterRanges(); 454 455 initToggles(); 455 456 })(); 457 Ajoutée 458 Ajoutée /* validiscan:slider-pause-control */ 459 Ajoutée /* 460 Ajoutée * Pause / play button of auto-advancing sliders (WCAG 2.2.2): wired to the 461 Ajoutée * slider's autoplay; sliders start paused when the visitor prefers reduced motion. 462 Ajoutée */ 463 Ajoutée (function sliderPauseControl() { 464 Ajoutée 'use strict'; 465 Ajoutée 466 Ajoutée function tinySlider(slider) { 467 Ajoutée const manager = window.PluginManager; 468 Ajoutée if (!manager || typeof manager.getPluginInstanceFromElement !== 'function') return null; 469 Ajoutée const plugin = manager.getPluginInstanceFromElement(slider, 'BaseSlider'); 470 Ajoutée return plugin && plugin._slider ? plugin._slider : null; 471 Ajoutée } 472 Ajoutée 473 Ajoutée function autoplays(slider) { 474 Ajoutée try { 475 Ajoutée const options = JSON.parse(slider.getAttribute('data-base-slider-options') || '{}') || {}; 476 Ajoutée return Boolean(options.slider && options.slider.autoplay); 477 Ajoutée } catch { 478 Ajoutée return false; 479 Ajoutée } 480 Ajoutée } 481 Ajoutée 482 Ajoutée function init() { 483 Ajoutée const reduceMotion = 484 Ajoutée window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches; 485 Ajoutée document.querySelectorAll('[data-slider-pause]').forEach(function (button) { 486 Ajoutée const slider = button.closest('[data-base-slider]'); 487 Ajoutée if (!slider || !autoplays(slider)) return; 488 Ajoutée 489 Ajoutée function setPaused(paused) { 490 Ajoutée slider.setAttribute('data-autoplay-paused', paused ? 'true' : 'false'); 491 Ajoutée button.textContent = button.getAttribute(paused ? 'data-label-play' : 'data-label-pause'); 492 Ajoutée const instance = tinySlider(slider); 493 Ajoutée if (instance) instance[paused ? 'pause' : 'play'](); 494 Ajoutée } 495 Ajoutée 496 Ajoutée button.hidden = false; 497 Ajoutée button.addEventListener('click', function () { 498 Ajoutée setPaused(slider.getAttribute('data-autoplay-paused') !== 'true'); 499 Ajoutée }); 500 Ajoutée if (reduceMotion) setPaused(true); 501 Ajoutée }); 502 Ajoutée } 503 Ajoutée 504 Ajoutée if (document.readyState === 'complete') init(); 505 Ajoutée else window.addEventListener('load', init); 506 Ajoutée })(); 507 Ajoutée /* /validiscan:slider-pause-control */ Resources/snippet/de_DE/kaffeekontor-nord.de-DE.json Modifications apportées à Resources/snippet/de_DE/kaffeekontor-nord.de-DE.json (lignes ajoutées : 6, lignes supprimées : 0)
Modifications apportées à Resources/snippet/de_DE/kaffeekontor-nord.de-DE.json (lignes ajoutées : 6, lignes supprimées : 0) Ligne avant Ligne après Modification Code 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 Ajoutée }, 197 Ajoutée "a11y": { 198 Ajoutée "slider": { 199 Ajoutée "pause": "Diashow anhalten", 200 Ajoutée "play": "Diashow abspielen" 201 Ajoutée } 196 202 } 197 203 } Resources/snippet/en_GB/kaffeekontor-nord.en-GB.json Modifications apportées à Resources/snippet/en_GB/kaffeekontor-nord.en-GB.json (lignes ajoutées : 6, lignes supprimées : 0)
Modifications apportées à Resources/snippet/en_GB/kaffeekontor-nord.en-GB.json (lignes ajoutées : 6, lignes supprimées : 0) Ligne avant Ligne après Modification Code 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 Ajoutée }, 197 Ajoutée "a11y": { 198 Ajoutée "slider": { 199 Ajoutée "pause": "Pause slideshow", 200 Ajoutée "play": "Play slideshow" 201 Ajoutée } 196 202 } 197 203 } Resources/views/storefront/element/cms-element-image-slider.html.twig Modifications apportées à Resources/views/storefront/element/cms-element-image-slider.html.twig (lignes ajoutées : 1, lignes supprimées : 0)
Modifications apportées à Resources/views/storefront/element/cms-element-image-slider.html.twig (lignes ajoutées : 1, lignes supprimées : 0) Ligne avant Ligne après Modification Code 57 57 <button type="button" class="base-slider-controls-next image-slider-controls-btn" data-slide-next> 58 58 {% sw_icon 'arrow-head-right' %} 59 59 </button> 60 Ajoutée <button type="button" class="btn btn-light base-slider-pause" data-slider-pause="true" data-label-pause="{{ 'a11y.slider.pause'|trans|striptags }}" data-label-play="{{ 'a11y.slider.play'|trans|striptags }}" hidden>{{ 'a11y.slider.pause'|trans|sw_sanitize }}</button> 60 61 </div> 61 62 {% endblock %} 62 63 </div> -
Ni texte clignotant ni texte défilant remove-blink-marquee Les éléments
<blink>et<marquee>des templates Twig deviennent des éléments statiques, avec le même contenu, les mêmes classes et les mêmes id, de sorte qu’aucun texte ne bouge tout seul.Les éléments
<blink>et<marquee>des templates Twig deviennent des éléments statiques, avec le même contenu, les mêmes classes et les mêmes id : un<span>pour blink, un<div>pour marquee, ou un<span>lorsque le marquee se trouve dans un paragraphe ou un élément de texte semblable. Les réglages de défilement du marquee sont retirés, de sorte qu’aucun texte ne bouge tout seul.- Règles couvertes
-
-
blinkAUTO -
marqueeAUTO
-
- Types de fichiers modifiés
-
.html.twig
replaces a seeded marquee and blink in the top bar; axe no longer reports them Données d’exemple Resources/views/storefront/layout/header/top-bar.html.twig Modifications apportées à Resources/views/storefront/layout/header/top-bar.html.twig (lignes ajoutées : 2, lignes supprimées : 2)
Modifications apportées à Resources/views/storefront/layout/header/top-bar.html.twig (lignes ajoutées : 2, lignes supprimées : 2) Ligne avant Ligne après Modification Code 4 4 {% block layout_header_top_bar_usp %} 5 5 <p class="top-bar-usp"> 6 6 {% sw_icon 'checkmark' style { size: 'xs' } %} 7 Supprimée <marquee class="top-bar-marquee" behavior="scroll" scrollamount="4"><span>{{ 'header.topBarUsp'|trans }}</span></marquee> 7 Ajoutée <span class="top-bar-marquee"><span>{{ 'header.topBarUsp'|trans }}</span></span> 8 8 </p> 9 9 {% endblock %} 10 10 13 13 <li class="top-bar-nav-item"> 14 14 <a class="top-bar-nav-link top-bar-help" href="{{ url('/contact') }}"> 15 15 {% sw_icon 'headset' style { size: 'xs' } %} 16 Supprimée <blink class="top-bar-blink">{{ 'header.topBarHelp'|trans }}</blink> 16 Ajoutée <span class="top-bar-blink">{{ 'header.topBarHelp'|trans }}</span> 17 17 </a> 18 18 </li> 19 19 </ul> -
Aucun son qui démarre tout seul mute-autoplay Une vidéo qui se lance toute seule est rendue muette et un son ne démarre plus tout seul, sauf la lecture automatique que définit le code d’un template ou un script et les lecteurs dans des cadres ; sur Shopware, la recette n’est pas utilisée pour les constats de
vs-media.Une vidéo qui se lance toute seule reçoit
mutedetplaysinline: elle continue ainsi de jouer en silence, comme une vidéo d’arrière-plan, et se lit dans la page sous Safari sur téléphone au lieu d’ouvrir le lecteur plein écran. Un son qui démarre tout seul ne le fait plus ; les visiteurs le lancent eux-mêmes. La lecture automatique que définit le code d’un template ou un script, ainsi que les lecteurs intégrés dans des cadres, sont laissés à une personne. Dans un scan Validiscan, le son qui démarre tout seul est signalé par le contrôle des médiasvs-mediade Validiscan, qui remplace la règleno-autoplay-audiod’axe-core.vs-media, qui couvre aussi les sous-titres et les transcriptions, est MANUAL : sur Shopware, un tel constat s’accompagne donc d’indications plutôt que de cette modification.- Règles couvertes
-
-
no-autoplay-audioAUTO contrôle assuré par vs-media -
vs-mediaMANUAL
-
- Types de fichiers modifiés
-
.html.twig
mutes a seeded autoplaying background video; vs-media no longer reports autoplay Données d’exemple Resources/views/storefront/block/cms-block-video.html.twig Modifications apportées à Resources/views/storefront/block/cms-block-video.html.twig (lignes ajoutées : 1, lignes supprimées : 1)
Modifications apportées à Resources/views/storefront/block/cms-block-video.html.twig (lignes ajoutées : 1, lignes supprimées : 1) Ligne avant Ligne après Modification Code 9 9 <h2 class="cms-block-title">{{ block.title }}</h2> 10 10 <p class="cms-video-text">{{ block.text }}</p> 11 11 <div class="cms-element-video"> 12 Supprimée <video class="cms-video" autoplay loop preload="none" width="1280" height="720" poster="{{ block.posterUrl }}"> 12 Ajoutée <video class="cms-video" autoplay loop preload="none" width="1280" height="720" poster="{{ block.posterUrl }}" muted playsinline> 13 13 <source src="{{ block.videoUrl }}" type="video/mp4"> 14 14 {% if block.captionsUrl %} 15 15 <track kind="captions" src="{{ block.captionsUrl }}" srclang="en" label="{{ 'general.captionsEnglish'|trans }}" default>
Formulaires, panier et contenu intégré
-
Des étiquettes reliées à leurs champs label-association Un champ dont le texte d’étiquette figure déjà sur la page, juste avant lui, est relié à ce texte.
Un champ de formulaire dont le texte d’étiquette figure déjà sur la page, juste avant le champ, est relié à ce texte. Un
<label>sansforen reçoit un qui pointe vers le champ. Un élément de texte que le thème désigne par sa classe comme un titre ou une étiquette, comme le nom d’un groupe de variantes sur une fiche produit, devient le<label>du champ, en gardant ses classes et sa propre ligne. Les lecteurs d’écran lisent alors l’étiquette lorsque le champ reçoit le focus. Un champ qui n’a qu’un texte indicatif (placeholder) est laissé à une personne, car rédiger une étiquette est une décision de contenu.- Règles couvertes
-
-
labelAUTO contrôle assuré par vs-forms-ecommerce -
select-nameASSISTED -
vs-forms-ecommerceAUTO
-
- Types de fichiers modifiés
-
.html.twig
turns the variant group titles into labels of their selects; select-name no longer fires Données d’exemple Resources/views/storefront/page/product-detail/configurator.html.twig Modifications apportées à Resources/views/storefront/page/product-detail/configurator.html.twig (lignes ajoutées : 1, lignes supprimées : 1)
Modifications apportées à Resources/views/storefront/page/product-detail/configurator.html.twig (lignes ajoutées : 1, lignes supprimées : 1) Ligne avant Ligne après Modification Code 13 13 {% for group in product.configurator %} 14 14 {% if group.display == 'select' %} 15 15 <div class="product-detail-configurator-group"> 16 Supprimée <div class="product-detail-configurator-group-title">{{ group.name }}</div> 16 Ajoutée <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) %} -
Des champs de compte, d’adresse et de contact que les navigateurs peuvent remplir autocomplete-tokens Les champs qui demandent des données propres au client, comme ceux des formulaires d’inscription, d’adresse et de connexion, reçoivent la valeur
autocompletequi correspond à ce qu’ils demandent, sauf si le code d’un template l’écrit.Les champs qui demandent des données propres au client, comme ceux des formulaires d’inscription, d’adresse, de connexion, de contact et de newsletter, reçoivent la valeur
autocompletequi correspond à ce qu’ils demandent, comme l’adresse e-mail, le prénom et le nom, le code postal, le numéro de téléphone ou le mot de passe. La valeur est déduite du type, du nom, de l’identifiant, de l’étiquette et du texte indicatif du champ. Les mots de passe reçoiventnew-passworddans les formulaires d’inscription etcurrent-passwordailleurs. Les champs de recherche, de code promo, de quantité, de captcha et de message restent tels quels, et une valeur que le code d’un template écrit est laissée à une personne. Les navigateurs peuvent alors remplir les champs, et les technologies d’assistance peuvent savoir à quoi sert chacun.- Règles couvertes
-
-
autocomplete-validAUTO contrôle assuré par vs-forms-ecommerce -
vs-forms-ecommerceAUTO
-
- Types de fichiers modifiés
-
.html.twig
adds tokens to the register, address, login, contact and newsletter fields; no autocomplete hits remain Données d’exemple Resources/views/storefront/component/account/login.html.twig Modifications apportées à Resources/views/storefront/component/account/login.html.twig (lignes ajoutées : 1, lignes supprimées : 1)
Modifications apportées à Resources/views/storefront/component/account/login.html.twig (lignes ajoutées : 1, lignes supprimées : 1) Ligne avant Ligne après Modification Code 19 19 name="username" 20 20 placeholder="{{ 'account.loginMailPlaceholder'|trans }}" 21 21 required 22 Supprimée autocomplete="off"> 22 Ajoutée autocomplete="email"> 23 23 </div> 24 24 25 25 <div class="form-group"> Resources/views/storefront/component/account/register.html.twig Modifications apportées à Resources/views/storefront/component/account/register.html.twig (lignes ajoutées : 8, lignes supprimées : 4)
Modifications apportées à Resources/views/storefront/component/account/register.html.twig (lignes ajoutées : 8, lignes supprimées : 4) Ligne avant Ligne après Modification Code 33 33 id="{{ formId }}FirstName" 34 34 name="firstName" 35 35 placeholder="{{ 'account.firstNamePlaceholder'|trans }}" 36 Supprimée required> 36 Ajoutée required 37 Ajoutée 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 Supprimée required> 45 Ajoutée required 46 Ajoutée 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 Supprimée required> 57 Ajoutée required 58 Ajoutée 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 Supprimée required> 68 Ajoutée required 69 Ajoutée 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 Modifications apportées à Resources/views/storefront/component/address/address-form.html.twig (lignes ajoutées : 8, lignes supprimées : 4)
Modifications apportées à Resources/views/storefront/component/address/address-form.html.twig (lignes ajoutées : 8, lignes supprimées : 4) Ligne avant Ligne après Modification Code 14 14 id="{{ prefix }}AddressStreet" 15 15 name="{{ prefix }}[street]" 16 16 placeholder="{{ 'address.streetPlaceholder'|trans }}" 17 Supprimée required> 17 Ajoutée required 18 Ajoutée 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 Supprimée required> 30 Ajoutée required 31 Ajoutée 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 Supprimée required> 42 Ajoutée required 43 Ajoutée 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 Supprimée required> 53 Ajoutée required 54 Ajoutée 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 Modifications apportées à Resources/views/storefront/element/cms-element-form.html.twig (lignes ajoutées : 4, lignes supprimées : 4)
Modifications apportées à Resources/views/storefront/element/cms-element-form.html.twig (lignes ajoutées : 4, lignes supprimées : 4) Ligne avant Ligne après Modification Code 18 18 </select> 19 19 </div> 20 20 <div class="form-group col-md-4"> 21 Supprimée <input type="text" class="form-control" id="contactFormFirstName" name="firstName" placeholder="{{ 'account.firstNamePlaceholder'|trans }}" required> 21 Ajoutée <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 Supprimée <input type="text" class="form-control" id="contactFormLastName" name="lastName" placeholder="{{ 'account.lastNamePlaceholder'|trans }}" required> 24 Ajoutée <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 Supprimée <input type="email" class="form-control" id="contactFormMail" name="email" placeholder="{{ 'account.emailPlaceholder'|trans }}" required> 31 Ajoutée <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 Supprimée <input type="tel" class="form-control" id="contactFormPhone" name="phone"> 35 Ajoutée <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 Modifications apportées à Resources/views/storefront/layout/footer/footer.html.twig (lignes ajoutées : 2, lignes supprimées : 1)
Modifications apportées à Resources/views/storefront/layout/footer/footer.html.twig (lignes ajoutées : 2, lignes supprimées : 1) Ligne avant Ligne après Modification Code 62 62 id="footerNewsletterMail" 63 63 class="form-control" 64 64 placeholder="{{ 'footer.newsletterPlaceholder'|trans }}" 65 Supprimée required> 65 Ajoutée required 66 Ajoutée 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"> -
Les changements de prix, de stock et de panier annoncés live-region-cart-variant Le prix, la disponibilité ou les totaux du panier que le script de la Storefront met à jour sur place deviennent des régions live que les lecteurs d’écran lisent sans interrompre, sauf si un script remplace l’élément lui-même.
Les parties d’une page que le script de la Storefront met à jour sur place, comme le prix après le choix d’une variante par un client, la disponibilité ou les totaux du panier, deviennent des régions live en mode poli. Les lecteurs d’écran lisent alors la nouvelle valeur une fois, en entier, sans interrompre. Lorsqu’un script remplace l’élément lui-même au lieu de son contenu, une région live ne fonctionnerait pas : la recette laisse donc cet élément à une personne.
- Règles couvertes
-
-
vs-live-updatesAUTO
-
- Types de fichiers modifiés
-
.html.twig
makes the variant price and the cart totals polite live regions; the updates are announced Données d’exemple Resources/views/storefront/page/checkout/cart/index.html.twig Modifications apportées à Resources/views/storefront/page/checkout/cart/index.html.twig (lignes ajoutées : 2, lignes supprimées : 2)
Modifications apportées à Resources/views/storefront/page/checkout/cart/index.html.twig (lignes ajoutées : 2, lignes supprimées : 2) Ligne avant Ligne après Modification Code 59 59 <span class="line-item-unit-price-label">{{ 'checkout.cartHeaderUnitPrice'|trans }}:</span> 60 60 <span class="line-item-unit-price-value">{{ item.unitPrice|currency }}*</span> 61 61 </div> 62 Supprimée <div class="line-item-total-price"> 62 Ajoutée <div class="line-item-total-price" aria-live="polite" aria-atomic="true"> 63 63 <span class="line-item-total-price-label">{{ 'checkout.cartHeaderTotalPrice'|trans }}:</span> 64 64 <span class="line-item-total-price-value" data-line-total>{{ item.totalPrice|currency }}*</span> 65 65 </div> 88 88 <div class="col-lg-4 checkout-aside"> 89 89 <div class="checkout-aside-summary"> 90 90 <h2 class="checkout-aside-summary-header">{{ 'checkout.summaryHeader'|trans }}</h2> 91 Supprimée <div class="checkout-aside-summary-totals" data-shipping-threshold="{{ shop.shippingThreshold }}" data-shipping-costs="{{ shop.shippingCosts }}"> 91 Ajoutée <div class="checkout-aside-summary-totals" data-shipping-threshold="{{ shop.shippingThreshold }}" data-shipping-costs="{{ shop.shippingCosts }}" aria-live="polite" aria-atomic="true"> 92 92 <dl class="checkout-aside-summary-list"> 93 93 <dt class="checkout-aside-summary-label">{{ 'checkout.summaryPositionPrice'|trans }}</dt> 94 94 <dd class="checkout-aside-summary-value" data-cart-subtotal>{{ cart.subtotal|currency }}*</dd> Resources/views/storefront/page/product-detail/buy-widget.html.twig Modifications apportées à Resources/views/storefront/page/product-detail/buy-widget.html.twig (lignes ajoutées : 1, lignes supprimées : 1)
Modifications apportées à Resources/views/storefront/page/product-detail/buy-widget.html.twig (lignes ajoutées : 1, lignes supprimées : 1) Ligne avant Ligne après Modification Code 17 17 {% endblock %} 18 18 19 19 {% block buy_widget_price %} 20 Supprimée <div class="product-detail-price-container"> 20 Ajoutée <div class="product-detail-price-container" aria-live="polite" aria-atomic="true"> 21 21 <meta itemprop="priceCurrency" content="{{ shop.currency.isoCode }}"> 22 22 <meta itemprop="price" content="{{ product.price }}"> 23 23 <p class="product-detail-price{% if product.listPrice %} with-list-price{% endif %}" data-price-display>{{ product.price|currency }}*</p> -
Des titres pour les cartes et les vidéos intégrées iframe-title Un cadre intégré sans titre reçoit un titre traduit qui dit ce qu’il montre, lorsque le code le révèle.
Un cadre intégré sans titre, comme une carte ou une vidéo YouTube ou Vimeo, reçoit un titre traduit, tiré des fichiers de snippets du thème, qui dit ce qu’il montre. La recette déduit ce que montre le cadre de son adresse, de sa classe et de son nom, ou du template qui l’entoure. Un cadre dont le code ne révèle pas le contenu ne reçoit aucun titre de la recette, car un titre inventé est pire que pas de titre.
- Règles couvertes
-
-
frame-titleAUTO
-
- Types de fichiers modifiés
-
.html.twig.json
titles the contact map frame through the snippets; frame-title no longer fires Données d’exemple Resources/snippet/de_DE/kaffeekontor-nord.de-DE.json Modifications apportées à Resources/snippet/de_DE/kaffeekontor-nord.de-DE.json (lignes ajoutées : 5, lignes supprimées : 0)
Modifications apportées à Resources/snippet/de_DE/kaffeekontor-nord.de-DE.json (lignes ajoutées : 5, lignes supprimées : 0) Ligne avant Ligne après Modification Code 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 Ajoutée }, 197 Ajoutée "a11y": { 198 Ajoutée "iframe": { 199 Ajoutée "map": "Karte" 200 Ajoutée } 196 201 } 197 202 } Resources/snippet/en_GB/kaffeekontor-nord.en-GB.json Modifications apportées à Resources/snippet/en_GB/kaffeekontor-nord.en-GB.json (lignes ajoutées : 5, lignes supprimées : 0)
Modifications apportées à Resources/snippet/en_GB/kaffeekontor-nord.en-GB.json (lignes ajoutées : 5, lignes supprimées : 0) Ligne avant Ligne après Modification Code 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 Ajoutée }, 197 Ajoutée "a11y": { 198 Ajoutée "iframe": { 199 Ajoutée "map": "Map" 200 Ajoutée } 196 201 } 197 202 } Resources/views/storefront/block/cms-block-map.html.twig Modifications apportées à Resources/views/storefront/block/cms-block-map.html.twig (lignes ajoutées : 2, lignes supprimées : 1)
Modifications apportées à Resources/views/storefront/block/cms-block-map.html.twig (lignes ajoutées : 2, lignes supprimées : 1) Ligne avant Ligne après Modification Code 11 11 <iframe class="cms-map-frame" 12 12 src="{{ url('/widgets/cms/map') }}" 13 13 width="1280" 14 Supprimée height="360"></iframe> 14 Ajoutée height="360" 15 Ajoutée title="{{ 'a11y.iframe.map'|trans|striptags }}"></iframe> 15 16 </div> 16 17 <p class="cms-map-address">{{ shop.company.street }}, {{ shop.company.zip }} {{ shop.company.city }}</p> 17 18 </div>
Contraste, images et commandes qui demandent du jugement
Le contraste du texte, les alternatives textuelles des images et les noms des commandes qui n’en ont pas demandent généralement du jugement : quelle couleur convient à votre marque, quels mots décrivent une image. Les règles qui les signalent ont le niveau ASSISTED, comme le montrent les listes ci-dessous. Pour un constat d’une règle ASSISTED, l’IA ne rédige une modification que si vous avez accepté la rédaction par IA, et Validiscan relit chaque modification avant sa livraison.
Les quatre recettes ci-dessous ne sont la correction standard d’aucune règle. Chacune ne couvre que les cas précis où le code du thème suffit à lui seul à prouver quelle doit être la modification. Deux d’entre elles, button-semantics et icon-accessible-name, couvrent aussi le contrôle de diaporama vs-carousel, du niveau AUTO : dans un projet, le moteur de correction les essaie sur ses constats lorsque la recette du bouton de pause ci-dessus ne peut pas les corriger. Les deux autres ne couvrent que des règles du niveau ASSISTED.
-
Des couleurs de texte suffisamment contrastées contrast-tokens Une couleur de texte qui échoue au contrôle du contraste et qui est définie à un seul endroit passe à la nuance la plus proche de la même teinte qui atteint le contraste requis ; recette non appliquée dans un projet.
Lorsqu’un texte échoue au contrôle du contraste et que sa couleur est définie à un seul endroit du thème, cet endroit passe à la nuance la plus proche de la même teinte qui atteint le contraste requis, de sorte que le design reste reconnaissable. Cet endroit peut être un champ de couleur de
theme.jsonavec la variable SCSS qui le répète, une variable SCSS ou une propriété personnalisée utilisée uniquement pour du texte, ou une seule déclarationcolor. Une couleur utilisée à plusieurs endroits ou aussi comme arrière-plan ou comme bordure, ainsi que les champs de couleur de base de Shopware pour la marque, les bordures, les arrière-plans, les messages d’état et le bouton d’achat, sont laissés à une personne. Une couleur enregistrée dans les réglages du thème de l’Administration l’emporte surtheme.json: si elle y a été modifiée, c’est aussi là qu’il faut la modifier. La règlecolor-contrasta le niveau ASSISTED : dans un projet, un constat de contraste suit donc la voie ASSISTED et cette recette ne lui est pas appliquée.- Règles couvertes
-
-
color-contrastASSISTED
-
- Types de fichiers modifiés
-
.scss
darkens the unit price colour to 4.5:1 with the same hue; axe clears it on both pages Données d’exemple Resources/app/storefront/src/scss/_variant-broken.scss Modifications apportées à Resources/app/storefront/src/scss/_variant-broken.scss (lignes ajoutées : 1, lignes supprimées : 1)
Modifications apportées à Resources/app/storefront/src/scss/_variant-broken.scss (lignes ajoutées : 1, lignes supprimées : 1) Ligne avant Ligne après Modification Code 45 45 /* Light grey unit prices, 3.1:1 (color-contrast). */ 46 46 .product-price-unit, 47 47 .product-detail-price-unit { 48 Supprimée color: #929292; 48 Ajoutée color: #757575; 49 49 } 50 50 51 51 /* Fixed two-line product names (vs-text-spacing). */ -
Des images décoratives masquées aux lecteurs d’écran decorative-image-alt Seules les images dont le template prouve qu’elles sont décoratives reçoivent un
altvide ouaria-hidden; recette non appliquée dans un projet.Une image n’est marquée comme décorative que lorsque le template prouve qu’elle n’apporte rien : elle se trouve dans un lien ou un bouton nommé autrement, c’est une icône placée à côté de sa propre étiquette textuelle, ou c’est un espaceur ou un séparateur. Un
<img>reçoit unaltvide, une image affichée avec la balisesw_thumbnailsde Shopware reçoit unaltvide dans ses attributs, et les icônes SVG reçoiventaria-hidden="true", de sorte que les lecteurs d’écran les ignorent au lieu de lire un nom de fichier. Toute autre image est du contenu, comme les logos de moyens de paiement dans un pied de page, et son alternative textuelle demande des mots qu’une personne choisit. Les règles que couvre cette recette ont le niveau ASSISTED : dans un projet, leurs constats suivent donc la voie ASSISTED et cette recette ne leur est pas appliquée.- Règles couvertes
-
-
image-altASSISTED -
role-img-altASSISTED -
svg-img-altASSISTED
-
- Types de fichiers modifiés
-
.html.twig
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"> -
Des noms pour les boutons et les liens qui n’ont qu’une icône icon-accessible-name Les boutons et les liens qui n’affichent qu’une icône reçoivent un nom traduit qui dit ce qu’ils font, lorsque le code révèle leur fonction ; dans un projet, la recette est essayée sur les commandes de diaporama que signale
vs-carousel.Les boutons et les liens qui n’affichent qu’une icône, comme la recherche, le panier, le compte, le lien du logo, les flèches de slider, les boutons de quantité et les choix de cookies, reçoivent un
aria-labeltraduit qui dit ce qu’ils font. La fonction est déduite des classes de la commande, de la cible de son lien, de l’icône qu’elle contient et du composant qui l’entoure. Une commande dont le code ne révèle pas la fonction, comme un lien de réseau social dont le réseau est stocké sous forme de données, est laissée à une personne, car un nom inventé est pire que pas de nom. Dans un projet, cette recette est essayée sur les commandes de diaporama que signalevs-carousel; les autres commandes qui n’ont qu’une icône sont signalées par des règles du niveau ASSISTED et suivent la voie ASSISTED.- Règles couvertes
-
-
button-nameASSISTED -
link-nameASSISTED -
vs-carouselAUTO -
vs-cookie-bannerASSISTED
-
- Types de fichiers modifiés
-
.html.twig.json
names every icon-only button of the home, product and cart pages; button-name no longer fires Données d’exemple Resources/snippet/de_DE/kaffeekontor-nord.de-DE.json Modifications apportées à Resources/snippet/de_DE/kaffeekontor-nord.de-DE.json (lignes ajoutées : 12, lignes supprimées : 0)
Modifications apportées à Resources/snippet/de_DE/kaffeekontor-nord.de-DE.json (lignes ajoutées : 12, lignes supprimées : 0) Ligne avant Ligne après Modification Code 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 Ajoutée }, 197 Ajoutée "a11y": { 198 Ajoutée "control": { 199 Ajoutée "search": "Suchen", 200 Ajoutée "previousSlide": "Vorherige Folie", 201 Ajoutée "nextSlide": "Nächste Folie", 202 Ajoutée "cookieSettings": "Cookie-Einstellungen", 203 Ajoutée "acceptCookies": "Alle Cookies akzeptieren", 204 Ajoutée "decreaseQuantity": "Menge verringern", 205 Ajoutée "increaseQuantity": "Menge erhöhen", 206 Ajoutée "removeFromCart": "Aus dem Warenkorb entfernen" 207 Ajoutée } 196 208 } 197 209 } Resources/snippet/en_GB/kaffeekontor-nord.en-GB.json Modifications apportées à Resources/snippet/en_GB/kaffeekontor-nord.en-GB.json (lignes ajoutées : 12, lignes supprimées : 0)
Modifications apportées à Resources/snippet/en_GB/kaffeekontor-nord.en-GB.json (lignes ajoutées : 12, lignes supprimées : 0) Ligne avant Ligne après Modification Code 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 Ajoutée }, 197 Ajoutée "a11y": { 198 Ajoutée "control": { 199 Ajoutée "search": "Search", 200 Ajoutée "previousSlide": "Previous slide", 201 Ajoutée "nextSlide": "Next slide", 202 Ajoutée "cookieSettings": "Cookie settings", 203 Ajoutée "acceptCookies": "Accept all cookies", 204 Ajoutée "decreaseQuantity": "Decrease quantity", 205 Ajoutée "increaseQuantity": "Increase quantity", 206 Ajoutée "removeFromCart": "Remove from cart" 207 Ajoutée } 196 208 } 197 209 } Resources/views/storefront/element/cms-element-image-gallery.html.twig Modifications apportées à Resources/views/storefront/element/cms-element-image-gallery.html.twig (lignes ajoutées : 2, lignes supprimées : 2)
Modifications apportées à Resources/views/storefront/element/cms-element-image-gallery.html.twig (lignes ajoutées : 2, lignes supprimées : 2) Ligne avant Ligne après Modification Code 31 31 32 32 {% if media|length > 1 %} 33 33 <div class="gallery-slider-controls"> 34 Supprimée <button type="button" class="base-slider-controls-prev gallery-slider-controls-prev" data-gallery-prev> 34 Ajoutée <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 Supprimée <button type="button" class="base-slider-controls-next gallery-slider-controls-next" data-gallery-next> 37 Ajoutée <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 Modifications apportées à Resources/views/storefront/element/cms-element-image-slider.html.twig (lignes ajoutées : 2, lignes supprimées : 2)
Modifications apportées à Resources/views/storefront/element/cms-element-image-slider.html.twig (lignes ajoutées : 2, lignes supprimées : 2) Ligne avant Ligne après Modification Code 46 46 47 47 {% block element_image_slider_controls %} 48 48 <div class="image-slider-controls-container"> 49 Supprimée <button type="button" class="base-slider-controls-prev image-slider-controls-btn" data-slide-prev> 49 Ajoutée <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 Supprimée <button type="button" class="base-slider-controls-next image-slider-controls-btn" data-slide-next> 57 Ajoutée <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 Modifications apportées à Resources/views/storefront/layout/cookie/cookie-permission.html.twig (lignes ajoutées : 2, lignes supprimées : 2)
Modifications apportées à Resources/views/storefront/layout/cookie/cookie-permission.html.twig (lignes ajoutées : 2, lignes supprimées : 2) Ligne avant Ligne après Modification Code 22 22 </p> 23 23 </div> 24 24 <div class="col-auto cookie-permission-actions"> 25 Supprimée <button type="button" class="btn cookie-permission-icon-btn js-cookie-configuration-toggle">{% sw_icon 'settings' %}</button> 26 Supprimée <button type="button" class="btn btn-primary cookie-permission-icon-btn js-cookie-accept-all-button">{% sw_icon 'checkmark' %}</button> 25 Ajoutée <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 Ajoutée <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 Modifications apportées à Resources/views/storefront/layout/header/search.html.twig (lignes ajoutées : 1, lignes supprimées : 1)
Modifications apportées à Resources/views/storefront/layout/header/search.html.twig (lignes ajoutées : 1, lignes supprimées : 1) Ligne avant Ligne après Modification Code 13 13 autocomplete="off" 14 14 autocapitalize="off" 15 15 placeholder="{{ 'header.searchPlaceholder'|trans }}" value="{{ page.searchTerm }}"> 16 Supprimée <button type="submit" class="btn header-search-btn"> 16 Ajoutée <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 Modifications apportées à Resources/views/storefront/page/checkout/cart/index.html.twig (lignes ajoutées : 3, lignes supprimées : 3)
Modifications apportées à Resources/views/storefront/page/checkout/cart/index.html.twig (lignes ajoutées : 3, lignes supprimées : 3) Ligne avant Ligne après Modification Code 39 39 </div> 40 40 <div class="line-item-quantity"> 41 41 <div class="input-group quantity-selector-group" data-quantity-selector="true"> 42 Supprimée <button type="button" class="btn btn-outline-light btn-minus js-btn-minus"> 42 Ajoutée <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 Supprimée <button type="button" class="btn btn-outline-light btn-plus js-btn-plus"> 53 Ajoutée <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 Supprimée <button type="button" class="btn btn-light btn-sm line-item-remove-button"> 67 Ajoutée <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 Modifications apportées à Resources/views/storefront/page/product-detail/buy-widget.html.twig (lignes ajoutées : 2, lignes supprimées : 2)
Modifications apportées à Resources/views/storefront/page/product-detail/buy-widget.html.twig (lignes ajoutées : 2, lignes supprimées : 2) Ligne avant Ligne après Modification Code 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 Supprimée <button type="button" class="btn btn-outline-light btn-minus js-btn-minus"> 67 Ajoutée <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 Supprimée <button type="button" class="btn btn-outline-light btn-plus js-btn-plus"> 78 Ajoutée <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> names the logo and account links; social links whose network is data are left for review Données d’exemple Resources/snippet/de_DE/kaffeekontor-nord.de-DE.json Modifications apportées à Resources/snippet/de_DE/kaffeekontor-nord.de-DE.json (lignes ajoutées : 6, lignes supprimées : 0)
Modifications apportées à Resources/snippet/de_DE/kaffeekontor-nord.de-DE.json (lignes ajoutées : 6, lignes supprimées : 0) Ligne avant Ligne après Modification Code 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 Ajoutée }, 197 Ajoutée "a11y": { 198 Ajoutée "control": { 199 Ajoutée "home": "Zur Startseite", 200 Ajoutée "account": "Ihr Konto" 201 Ajoutée } 196 202 } 197 203 } Resources/snippet/en_GB/kaffeekontor-nord.en-GB.json Modifications apportées à Resources/snippet/en_GB/kaffeekontor-nord.en-GB.json (lignes ajoutées : 6, lignes supprimées : 0)
Modifications apportées à Resources/snippet/en_GB/kaffeekontor-nord.en-GB.json (lignes ajoutées : 6, lignes supprimées : 0) Ligne avant Ligne après Modification Code 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 Ajoutée }, 197 Ajoutée "a11y": { 198 Ajoutée "control": { 199 Ajoutée "home": "Go to the homepage", 200 Ajoutée "account": "Your account" 201 Ajoutée } 196 202 } 197 203 } Resources/views/storefront/layout/header/actions.html.twig Modifications apportées à Resources/views/storefront/layout/header/actions.html.twig (lignes ajoutées : 2, lignes supprimées : 1)
Modifications apportées à Resources/views/storefront/layout/header/actions.html.twig (lignes ajoutées : 2, lignes supprimées : 1) Ligne avant Ligne après Modification Code 3 3 {% block layout_header_actions_account %} 4 4 <div class="header-account"> 5 5 <a href="{{ url('/account/login') }}" 6 Supprimée class="btn account-menu-btn header-actions-btn"> 6 Ajoutée class="btn account-menu-btn header-actions-btn" 7 Ajoutée 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 Modifications apportées à Resources/views/storefront/layout/header/logo.html.twig (lignes ajoutées : 1, lignes supprimées : 1)
Modifications apportées à Resources/views/storefront/layout/header/logo.html.twig (lignes ajoutées : 1, lignes supprimées : 1) Ligne avant Ligne après Modification Code 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 Supprimée <a class="header-logo-main-link" href="{{ url('/') }}"> 5 Ajoutée <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') }}"
Détails : les niveaux, le thème de test, les contrôles de chaque modification et le texte dans les langues de votre boutique
Une recette est une modification déterministe pour un type d’échec : le même code reçoit toujours la même modification. Validiscan dispose de 20 recettes pour les thèmes Shopware. Chacune n’intervient que là où le code du thème montre quelle modification est la bonne. Là où il ne le montre pas, la recette ne change rien. Elle ne devine pas.
Sous chaque recette figurent les règles qu’elle couvre, avec le niveau de chaque règle dans le catalogue de Validiscan pour Shopware. AUTO signifie qu’une recette est la correction standard de la règle. ASSISTED signifie que la correction demande du jugement : une modification est donc rédigée, puis relue. MANUAL signifie que la règle demande la décision d’une personne et s’accompagne d’indications, et non d’une modification du code. Dans un projet, les recettes sont appliquées aux constats des règles du niveau AUTO. Lorsqu’une recette énumère aussi une règle du niveau ASSISTED ou MANUAL, un constat de cette règle suit à la place la voie ASSISTED ou MANUAL. Une règle dont le contrôle est assuré par un autre contrôle n’est pas exécutée seule lors d’un scan : cet autre contrôle signale le même échec.
Les types de fichiers et l’avant et l’après de chaque recette proviennent des tests internes de Validiscan. Ils s’exécutent sur le thème de test Shopware de Validiscan, un plugin de thème construit sur la Storefront par défaut de Shopware 6, dans lequel des échecs d’accessibilité ont été introduits volontairement. Chaque test génère les pages à partir des templates du thème avant et après la modification et exécute la même règle sur les deux : l’échec doit être signalé avant et ne plus l’être après, et la modification ne doit pas provoquer de nouvel échec de cette règle. Les pages sont produites par un moteur de rendu de test, et non par une installation complète de Shopware ; les fichiers de votre thème seront différents.
Avant que Validiscan ne relise une modification, chaque fichier modifié est contrôlé. Les templates Twig sont analysés avec les balises propres à Shopware, comme sw_extends et sw_include, que l’analyseur connaît ; ils ne sont jamais compilés ni exécutés. Les feuilles de style subissent un contrôle de structure, les fichiers de snippets et theme.json sont analysés comme du JSON, et le JavaScript subit un contrôle de syntaxe.
Lorsqu’une recette ajoute un texte visible ou un nom, comme les mots d’un lien d’évitement ou le nom d’un bouton à icône, elle utilise un snippet dans le template. Le texte va dans le fichier de snippets anglais du thème, que la recette crée si le thème n’en a pas, et dans son fichier de snippets allemand lorsque le thème en possède un. Les snippets qui existent déjà conservent leur texte. Aucun texte n’est ajouté pour les autres langues de votre boutique.
Qu’est-ce qui reste MANUAL sur Shopware ?
Les échecs qui exigent une décision sur le contenu ou le comportement qu’une modification de code prédéfinie ne peut pas prendre, par exemple les sous-titres et transcriptions de vos vidéos et contenus audio, restent MANUAL sur Shopware. Pour un constat d’une règle MANUAL, Validiscan donne des indications pour le corriger, et non une modification de votre code.
Les règles ci-dessous sont exécutées lors d’un scan et ont le niveau MANUAL sur Shopware.
-
meta-refreshL’actualisation différée de moins de 20 heures ne doit pas être utilisée -
nested-interactiveLes éléments interactifs ne doivent pas être imbriqués -
scrollable-region-focusableLes zones défilantes doivent être accessibles au clavier -
server-side-image-mapLes images réactives côté serveur ne doivent pas être utilisées -
vs-keyboard-trapLe focus clavier ne doit jamais rester piégé -
vs-focus-orderL’ordre de tabulation doit suivre l’ordre visuel -
vs-draggingLes éléments à faire glisser doivent offrir une alternative à pointeur unique -
vs-mediaLes vidéos ont besoin de sous-titres, l’audio d’une transcription, et rien ne doit démarrer automatiquement avec le son -
vs-documentsLes documents liés nécessitent une vérification manuelle de l’accessibilité
Détails : ce que reçoit un constat MANUAL, et ce qu’un projet laisse de côté
Pour un constat d’une règle MANUAL, Validiscan donne des indications sur la façon de le corriger, et non une modification de votre code. Ces échecs exigent une décision sur le contenu ou le comportement qu’une modification de code prédéfinie ne peut pas prendre, par exemple les sous-titres et les transcriptions de vos vidéos et de vos contenus audio, un moyen de sortir d’un widget qui piège le focus clavier, ou un second moyen d’utiliser une commande qui ne fonctionne qu’en la faisant glisser.
Le travail sur les constats MANUAL qui exigent vos propres décisions de contenu ne fait pas partie d’un projet, pas plus que les PDF. Ce que le scan teste automatiquement et ce qui est vérifié à la main
Que devez-vous fournir ?
Vous fournissez votre autorisation d’un scan complet, une voie d’accès à votre plugin de thème, votre réponse sur la rédaction par IA des corrections ASSISTED, un développeur qui relit les modifications, compile et déploie le thème, certains réglages de l’Administration, les nouveaux textes dans d’autres langues que l’anglais et l’allemand, et vos décisions sur ce qui reste MANUAL.
- Votre autorisation pour un scan complet de votre boutique, que Validiscan enregistre avant le scan. Un scan complet met un produit dans le panier et ouvre la première étape du tunnel de commande, sans finaliser d’achat ni saisir de données de paiement.
- Une voie d’accès à votre thème : l’accès au dépôt GitHub qui contient le plugin de thème, ou un ZIP du dossier du plugin sous
custom/plugins, téléversé dans le portail client. - Votre réponse à la question de savoir si l’IA peut rédiger des corrections du niveau ASSISTED. La rédaction par IA reste désactivée tant que vous n’avez pas donné votre accord.
- Un développeur qui relit les modifications, fusionne la pull request ou applique le lot de correctifs, compile le thème et le déploie.
- Les réglages de l’Administration de Shopware que les corrections ne modifient pas : les méta-titres des pages qui n’en ont pas, la langue d’un contenu rédigé dans une autre langue que celle de votre boutique, et une couleur enregistrée dans les réglages du thème lorsqu’une correction de contraste modifie cette couleur.
- Les textes pour les langues de votre boutique autres que l’anglais et l’allemand, lorsqu’une correction ajoute un nouveau texte.
- Vos décisions sur ce qui reste MANUAL, comme les sous-titres de vos vidéos.
Détails : une fois les modifications en ligne, et ce que couvre un projet
Une fois les modifications en ligne, un scan de vérification contrôle de nouveau les pages concernées, et le Remediation Evidence Package consigne le résultat. Le déroulement d’un projet, étape par étape
Un projet couvre une boutique : un domaine et un thème. Il vaut pour une vitrine construite sur un thème ; une vitrine headless est traitée sur demande.
Sources
2 sources, toutes vérifiées pour cette page le 6 octobre 2026.
Documentation de Shopware pour les développeurs 2
- Add SCSS Styling and JavaScript to a Theme · Shopware · vérifiée le
- Add custom JavaScript · Shopware · vérifiée le
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 gratuiteOu é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