Rettelser af tilgængelighed i koden til dit tema på Shopware
Validiscan retter tilgængelighedsfejl i Twig-skabelonerne, SCSS, storefrontens JavaScript og snippet-filerne i dit temaplugin til Shopware 6. Intet når din live webshop, før din udvikler merger eller anvender ændringerne og ruller temaet ud.
Senest opdateret:
På denne side: 6 svar
Hvad ændrer Validiscan i et Shopware-tema?
Validiscan ændrer kun filer i de mapper, hvor et storefront-tema til Shopware 6 har sine kildefiler, Resources/views, Resources/ og Resources/snippet, samt temaets theme.json. En ændring af enhver anden fil består ikke valideringen og leveres aldrig, og ingen rettelse installerer et plugin eller tilføjer et overlay-script.
Indstillinger, som du har i Shopware-administrationen, for eksempel metatitler eller temafarver, der er gemt dér, er ikke filer i temaet, så rettelserne ændrer dem ikke. Et projekt dækker ét domæne og ét tema; indlejret tredjepartsindhold som betalings- eller chatwidgets er ikke en del af det.
Detaljer: mapperne, hvordan en ændring ser ud, og de to opskrifter, der ændrer storefront-scriptet
Validiscan ændrer kun filer i de mapper, hvor et storefront-tema til Shopware 6 har sine kildefiler: Twig-skabelonerne i Resources/views, SCSS- og JavaScript-kilderne i Resources/, snippet-filerne med storefrontens tekst i Resources/snippet og temaets theme.json. En ændring af enhver anden fil, for eksempel de kompilerede filer i Resources/ eller pluginets PHP-kode og konfiguration, består ikke valideringen. En ændring, der ikke består valideringen, kan ikke godkendes og leveres derfor aldrig.
Hver ændring er en almindelig redigering af en temafil, som din udvikler kan læse linje for linje. Små ændringer, for eksempel en tilføjet attribut eller en rettet farveværdi, foretages dér, hvor koden allerede står. Nye stilregler og nye scriptblokke står mellem kommentarer, der angiver opskriftens navn, for eksempel /* validiscan:, så de er nemme at finde. To opskrifter ændrer temaets eget storefront-script: Den ene forbinder en pauseknap med billedslideren, og den anden sørger for, at et scripts automatiske afspilning ikke starter, når en besøgende har bedt om mindre bevægelse. Ingen rettelse installerer et plugin eller tilføjer et script, som retter dine sider, efter at de er indlæst, sådan som et overlay gør.
Hvordan får Validiscan adgang til dit Shopware-tema?
Gennem et GitHub-repository eller som en ZIP-fil med temapluginet, uploadet i kundeportalen, fordi Validiscan udarbejder hver rettelse i en kopi af kildekoden til dit Shopware-temaplugin. Hvilken måde der passer, afhænger af, hvor koden ligger: Et repository giver en pull request, en ZIP-fil giver en patchpakke.
| Vej ind | Det giver du | Ændringerne kommer tilbage som |
|---|---|---|
| Gennem dit GitHub-repository | Adgang til det repository, der rummer temapluginet, gennem Validiscans GitHub-app eller et adgangstoken | En pull request |
| Ud fra en ZIP-fil med temapluginet | Temapluginets mappe under custom/ som én ZIP-fil på op til 100 MB, uploadet i kundeportalen af en administrator i din organisation | En patchpakke |
Gennem dit GitHub-repository
Hvis koden til dit temaplugin ligger i et GitHub-repository, giver du Validiscan adgang til det repository: Du installerer Validiscans GitHub-app på det eller giver Validiscan et adgangstoken til det. Validiscans opsætning angiver appens tilladelser som læse- og skriveadgang til repositoriets indhold og pull requests og læseadgang til dets metadata, og intet andet. Et token skal have de samme tilladelser til netop det ene repository.
Temapluginet kan ligge i roden af repositoriet eller dybere nede, som i custom/: Opskrifterne finder temaets filer ud fra Shopwares mappekonventioner. Ændringerne kommer så som en pull request.
Ud fra en ZIP-fil med temapluginet
Hvis koden ikke ligger i et GitHub-repository, laver din udvikler en ZIP-fil med temapluginet. Kundeportalens vejledning til Shopware lyder: »Bed din udvikler om en ZIP-fil med dit temaplugin: dets mappe under custom/plugins, sådan som den er udrullet i din webshop.« En administrator i din organisation uploader derefter filen i kundeportalen som én ZIP-fil på op til 100 MB. Validiscan udarbejder ændringerne ud fra den kopi af dit tema og sender dem tilbage som en patchpakke.
Uden nogen af de to veje har Validiscan ingen kode at ændre, og der udarbejdes ingen rettelse.
Hvordan når ændringerne frem til din webshop?
Ændringerne kommer som en pull request eller som en patchpakke, og din udvikler afgør, hvornår de går live. Validiscan leverer kun ændringer, som Validiscan har gennemgået og godkendt, og ændrer aldrig temaet eller koden i din live Shopware-webshop; levering som en upubliceret kopi af temaet findes kun på Shopify.
- Validiscan leverer de ændringer, som Validiscan har gennemgået og godkendt: en pull request på en ny branch eller en patchpakke til din udvikler.
- Din udvikler gennemgår ændringerne. Ved en pull request beder tjeklisten om et forhåndsvisnings- eller staging-miljø, ikke den live webshop, og om en kontrol af de berørte sider, også med tastaturet alene.
- Din udvikler merger pull requesten eller anvender patchpakken.
- Din udvikler bygger temaet: Ændringer i SCSS træder i kraft, når temaet kompileres igen, og ændringer i JavaScript, når storefronten bygges igen.
- Din udvikler ruller temaet ud. Når ændringerne er live, kontrollerer en verifikationsscanning de berørte sider igen.
En pull request
Med adgang til dit repository opretter Validiscan en ny branch med navnet validiscan/, committer hver rettelse for sig og åbner én pull request med en oversigtstabel, en forklaring af hver ændring og en tjekliste til gennemgangen. Der pushes intet til din standardbranch. Tjeklisten beder din udvikler om at rulle branchen ud i et forhåndsvisnings- eller staging-miljø, ikke i den live webshop, og om dér at kontrollere de berørte sider, også med tastaturet alene, før der merges.
En patchpakke
Ud fra den uploadede ZIP-fil udarbejder Validiscan et zip-arkiv og sender det til din udvikler. Det indeholder PATCH.md med hver ændring og en vejledning i at anvende den, alle ændringer i én patchfil, som kan anvendes med git apply, én patchfil pr. rettelse, de komplette ændrede filer og en README.md. Din udvikler anvender ændringerne, tester dem og ruller temaet ud. Hvad en pull request og en patchpakke indeholder
Sådan bygges temaet
En Shopware-webshop leverer ikke temaets SCSS- og JavaScript-kilder, som de er: De bygges først. Ændringer i SCSS træder i kraft, når temaet kompileres igen, for eksempel med bin/, som Shopwares udviklerdokumentation om styling af temaer beskriver. Ændringer i storefrontens JavaScript træder i kraft, når storefronten bygges igen, som beskrevet i Shopwares dokumentation om JavaScript i storefronten. Din udvikler udfører disse trin, når det ændrede tema rulles ud. Sådan kommer tilgængelighedsrettelser ind i et Shopware-tema, og hvad en temaopdatering kan fortryde
Hvad ændrer opskrifterne i et Shopware-tema?
Hver af Validiscans 20 opskrifter til Shopware-temaer er en deterministisk ændring for én slags fejl: Den samme kode får altid den samme ændring. En opskrift foretager kun en ændring, hvor temaets kode viser, hvad den rigtige ændring er; hvor den ikke gør det, ændrer opskriften intet.
Sidestruktur og navigation
-
Sidens sprog i basislayoutet html-lang
<html>-elementet i basislayoutet får en gyldiglang-attribut, hvor den mangler, eller hvor temaet udskriver en landestandardkode somen_GB.<html>-elementet i storefrontens basislayout får en gyldiglang-attribut, så skærmlæsere udtaler siden på det rigtige sprog. Hvor attributten mangler, tilføjer opskriften koden for webshoppens aktive sprog, for eksempelde-DE, som er den værdi, Shopwares egen basisskabelon udskriver. Hvor temaet udskriver en landestandardkode (locale) somen_GB, der ikke er et gyldigt sprogtag, omsætter skabelonen den nu tilen-GB. En side, hvis indhold er skrevet på et andet sprog end webshoppens, for eksempel en tysk juridisk tekst i en engelsksproget webshop, overlades til dig: Indholdets sprog angives i Shopware-administrationen eller markeres i selve teksten.- Regler, den dækker
-
-
html-has-langAUTO kontrolleres via vs-lang -
html-lang-validAUTO kontrolleres via vs-lang -
vs-langAUTO
-
- Filtyper, den ændrer
-
.html.twig
normalises the locale code of the base layout; German content pages are left to the merchant Eksempeldata Resources/views/storefront/base.html.twig Ændringer i Resources/views/storefront/base.html.twig: 1 tilføjet, 1 fjernet
Ændringer i Resources/views/storefront/base.html.twig: 1 tilføjet, 1 fjernet Linje før Linje efter Ændring Kode 9 9 {% block base_doctype %}<!DOCTYPE html>{% endblock %} 10 10 11 11 {% block base_html %} 12 Fjernet <html lang="{{ page.lang }}" itemscope="itemscope" itemtype="https://schema.org/WebPage"> 12 Tilføjet <html lang="{{ page.lang|replace({'_': '-'}) }}" itemscope="itemscope" itemtype="https://schema.org/WebPage"> 13 13 {% endblock %} 14 14 15 15 {% block base_head %} -
Spring over-link, hovedområde og navngivne menuer skip-link-main Afhængigt af, hvad scanningen fandt: et spring over-link til hovedindholdet, et markeret hovedområde eller navne til navigationsområderne.
Afhængigt af, hvad scanningen fandt, tilføjer opskriften et spring over-link, markerer hovedindholdet eller giver navigationsområderne navne. Spring over-linket bliver det første element, en tastaturbruger når på hver side. Det er skjult, indtil det får fokus, og det fører til hovedindholdet. Hvor ingen skabelon markerer hovedindholdet som
<main>, bliver basislayoutets indholdsområde sidens<main>-område. Linkets tekst er snippettengeneral.skipToContent, på engelsk »Skip to main content«. Et eksisterende spring over-link får hovedindholdet som mål. Navigationsområder uden navn får et, hentet fra deres overskrift eller deres formål, for eksempel Main navigation, Service navigation eller Breadcrumb. Et navigationsområde, hvis formål er uklart, eller som ville få samme navn som et andet, overlades til et menneske.- Regler, den dækker
-
-
bypassAUTO kontrolleres via vs-headings-landmarks -
landmark-one-mainAUTO kontrolleres via vs-headings-landmarks -
regionAUTO -
skip-linkAUTO -
vs-headings-landmarksAUTO
-
- Filtyper, den ændrer
-
.html.twig.json.scss
adds a skip link, a <main> landmark and navigation names; the landmark problems are gone Eksempeldata Resources/app/storefront/src/scss/base.scss Ændringer i Resources/app/storefront/src/scss/base.scss: 24 tilføjet, 0 fjernet
Ændringer i Resources/app/storefront/src/scss/base.scss: 24 tilføjet, 0 fjernet Linje før Linje efter Ændring Kode 1708 1708 margin: 8px 0 0; 1709 1709 font-size: 0.875rem; 1710 1710 } 1711 Tilføjet 1712 Tilføjet /* validiscan:skip-link-main */ 1713 Tilføjet /* Skip link: parked off-screen, shown at the top left when it receives keyboard focus (WCAG 2.4.1). */ 1714 Tilføjet .skip-to-content-link { 1715 Tilføjet position: absolute; 1716 Tilføjet top: 8px; 1717 Tilføjet left: -10000px; 1718 Tilføjet z-index: 10000; 1719 Tilføjet padding: 12px 16px; 1720 Tilføjet border: 2px solid #1f2328; 1721 Tilføjet background: #ffffff; 1722 Tilføjet color: #1f2328; 1723 Tilføjet font-weight: 700; 1724 Tilføjet } 1725 Tilføjet 1726 Tilføjet .skip-to-content-link:focus { 1727 Tilføjet left: 8px; 1728 Tilføjet } 1729 Tilføjet 1730 Tilføjet /* The skip target takes focus programmatically; it needs no focus ring of its own. */ 1731 Tilføjet #content-main:focus { 1732 Tilføjet outline: none; 1733 Tilføjet } 1734 Tilføjet /* /validiscan:skip-link-main */ Resources/snippet/de_DE/kaffeekontor-nord.de-DE.json Ændringer i Resources/snippet/de_DE/kaffeekontor-nord.de-DE.json: 7 tilføjet, 0 fjernet
Ændringer i Resources/snippet/de_DE/kaffeekontor-nord.de-DE.json: 7 tilføjet, 0 fjernet Linje før Linje efter Ændring Kode 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 Tilføjet }, 197 Tilføjet "a11y": { 198 Tilføjet "navigation": { 199 Tilføjet "breadcrumb": "Brotkrümelnavigation", 200 Tilføjet "service": "Servicenavigation", 201 Tilføjet "main": "Hauptnavigation" 202 Tilføjet } 196 203 } 197 204 } Resources/snippet/en_GB/kaffeekontor-nord.en-GB.json Ændringer i Resources/snippet/en_GB/kaffeekontor-nord.en-GB.json: 7 tilføjet, 0 fjernet
Ændringer i Resources/snippet/en_GB/kaffeekontor-nord.en-GB.json: 7 tilføjet, 0 fjernet Linje før Linje efter Ændring Kode 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 Tilføjet }, 197 Tilføjet "a11y": { 198 Tilføjet "navigation": { 199 Tilføjet "breadcrumb": "Breadcrumb", 200 Tilføjet "service": "Service navigation", 201 Tilføjet "main": "Main navigation" 202 Tilføjet } 196 203 } 197 204 } Resources/views/storefront/base.html.twig Ændringer i Resources/views/storefront/base.html.twig: 4 tilføjet, 3 fjernet
Ændringer i Resources/views/storefront/base.html.twig: 4 tilføjet, 3 fjernet Linje før Linje efter Ændring Kode 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 Fjernet {% endblock %} 25 Tilføjet <a class="skip-to-content-link" href="#content-main">{{ 'general.skipToContent'|trans|sw_sanitize }}</a> 26 Tilføjet {% 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 Fjernet <div class="content-main"> 52 Tilføjet <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 Fjernet </div> 68 Tilføjet </main> 68 69 {% endblock %} 69 70 70 71 {% block base_footer %} Resources/views/storefront/layout/breadcrumb.html.twig Ændringer i Resources/views/storefront/layout/breadcrumb.html.twig: 1 tilføjet, 1 fjernet
Ændringer i Resources/views/storefront/layout/breadcrumb.html.twig: 1 tilføjet, 1 fjernet Linje før Linje efter Ændring Kode 1 1 {% block layout_breadcrumb %} 2 Fjernet <nav class="breadcrumb-nav"> 2 Tilføjet <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 Ændringer i Resources/views/storefront/layout/footer/footer.html.twig: 2 tilføjet, 2 fjernet
Ændringer i Resources/views/storefront/layout/footer/footer.html.twig: 2 tilføjet, 2 fjernet Linje før Linje efter Ændring Kode 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 Fjernet <nav class="footer-column-content"> 26 Tilføjet <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 Fjernet <nav class="footer-column-content"> 41 Tilføjet <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 Ændringer i Resources/views/storefront/layout/header/top-bar.html.twig: 1 tilføjet, 1 fjernet
Ændringer i Resources/views/storefront/layout/header/top-bar.html.twig: 1 tilføjet, 1 fjernet Linje før Linje efter Ændring Kode 1 1 {% block layout_header_top_bar %} 2 2 <div class="top-bar"> 3 Fjernet <nav class="top-bar-nav"> 3 Tilføjet <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 Ændringer i Resources/views/storefront/layout/navigation/navigation.html.twig: 2 tilføjet, 1 fjernet
Ændringer i Resources/views/storefront/layout/navigation/navigation.html.twig: 2 tilføjet, 1 fjernet Linje før Linje efter Ændring Kode 3 3 <div class="container"> 4 4 {% block layout_main_navigation_menu %} 5 5 <nav class="nav main-navigation-menu" itemscope="itemscope" 6 Fjernet itemtype="https://schema.org/SiteNavigationElement"> 6 Tilføjet itemtype="https://schema.org/SiteNavigationElement" 7 Tilføjet 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 %} -
En titel på hver side document-title-template Hvor layoutet kun skriver metatitlen ind i
<title>, får titlen webshoppens navn som reserveværdi, så ingen side har en tom titel.Hvor temaets layout kun skriver sidens metatitel ind i
<title>, får kategorier og CMS-sider uden metatitel en tom titel. Opskriften beholder temaets egen titel og giver den en reserveværdi: webshoppens navn, hentet dér, hvor temaet allerede udskriver det, eller, hvis det ikke gør det, fra webshoppens navn i Shopwares grundindstillinger. Ingen side har så en tom titel. En titel, der kun er webshoppens navn, siger stadig ikke, hvad siden er, så disse sider har brug for en metatitel i Shopware-administrationen. Titler, der allerede har en reserveværdi eller fast tekst, bliver, som de er.- Regler, den dækker
-
-
document-titleAUTO
-
- Filtyper, den ændrer
-
.html.twig
gives the layout title a shop-name fallback and the empty CMS title is gone Eksempeldata Resources/views/storefront/layout/meta.html.twig Ændringer i Resources/views/storefront/layout/meta.html.twig: 1 tilføjet, 1 fjernet
Ændringer i Resources/views/storefront/layout/meta.html.twig: 1 tilføjet, 1 fjernet Linje før Linje efter Ændring Kode 36 36 {% endblock %} 37 37 38 38 {% block layout_head_title %} 39 Fjernet <title>{{ page.metaTitle }}</title> 39 Tilføjet <title>{{ page.metaTitle|default(shop.name) }}</title> 40 40 {% endblock %} 41 41 42 42 {% block layout_head_stylesheet %} -
Overskrifter uden oversprungne niveauer heading-levels En overskrift, der springer et niveau over, flyttes op sammen med skabelonens overskrifter på samme niveau eller dybere og bevarer sit udseende.
En overskrift, der springer et niveau over, for eksempel en h3 lige efter en h1, flyttes op til det næste niveau, og skabelonens øvrige overskrifter på det niveau eller et dybere flyttes med, så skabelonens egen disposition bevares. Hvor skabelonen sætter overskriftens tag i en variabel, ændres variablen. Klasser bevares, og hvor ingen klasse bestemmer størrelsen, bevarer en Bootstrap-overskriftsklasse det gamle udseende. På en side uden hovedoverskrift bliver det element, der allerede er sidens titel i dens egen skabelon, til h1, og dets udseende bevares. Har en side intet sådant element, tilføjer opskriften ingen overskrift, fordi en ny overskrift først skal formuleres.
- Regler, den dækker
-
-
heading-orderAUTO kontrolleres via vs-headings-landmarks -
page-has-heading-oneAUTO kontrolleres via vs-headings-landmarks -
vs-headings-landmarksAUTO
-
- Filtyper, den ændrer
-
.html.twig
moves a static grid title from h3 to h2; the skipped level is gone Eksempeldata Resources/views/storefront/block/cms-block-product-grid.html.twig Ændringer i Resources/views/storefront/block/cms-block-product-grid.html.twig: 1 tilføjet, 1 fjernet
Ændringer i Resources/views/storefront/block/cms-block-product-grid.html.twig: 1 tilføjet, 1 fjernet Linje før Linje efter Ændring Kode 5 5 {% block block_product_grid %} 6 6 <div class="cms-block cms-block-product-grid"> 7 7 <div class="cms-block-container"> 8 Fjernet <h3 class="cms-block-title">{{ block.title }}</h3> 8 Tilføjet <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 } %}
Tastaturbrug og fokus
-
En synlig fokusmarkering focus-visible-styles Én markering af tastaturfokus i temaets brandfarve eller den nærmeste nuance i samme farvetone med en kontrast på mindst 3:1 mod sidens baggrund.
Hovedstilarket får én markering af tastaturfokus: en ubrudt streg på 2 pixels, 2 pixels fra elementet, i temaets brandfarve. Hvor den farve er for lys, bruges den nærmeste nuance i samme farvetone, som har en kontrast på mindst 3:1 mod sidens baggrund. Temaregler, der fjerner markeringen ved fokus, gælder nu kun for fokus med musen: Et klik bevarer temaets udseende, og tastaturfokus viser markeringen. Regler, der viser fokus på anden måde, bevares. På mørke områder, for eksempel en topbjælke, kan markeringen have brug for en lysere farve, og det kontrollerer din udvikler i forhåndsvisningen.
- Regler, den dækker
-
-
vs-focus-visibleAUTO
-
- Filtyper, den ændrer
-
.scss
adds a brand-coloured :focus-visible ring and scopes the outline resets Eksempeldata Resources/app/storefront/src/scss/_variant-broken.scss Ændringer i Resources/app/storefront/src/scss/_variant-broken.scss: 5 tilføjet, 5 fjernet
Ændringer i Resources/app/storefront/src/scss/_variant-broken.scss: 5 tilføjet, 5 fjernet Linje før Linje efter Ændring Kode 21 21 } 22 22 23 23 /* "Remove the ugly blue ring" (vs-focus-visible). */ 24 Fjernet .header-actions-btn:focus, 25 Fjernet .header-search-btn:focus, 26 Fjernet .main-navigation-link:focus, 27 Fjernet .product-name:focus, 28 Fjernet .footer-link:focus { 24 Tilføjet .header-actions-btn:focus:not(:focus-visible), 25 Tilføjet .header-search-btn:focus:not(:focus-visible), 26 Tilføjet .main-navigation-link:focus:not(:focus-visible), 27 Tilføjet .product-name:focus:not(:focus-visible), 28 Tilføjet .footer-link:focus:not(:focus-visible) { 29 29 outline: 0; 30 30 box-shadow: none; 31 31 } Resources/app/storefront/src/scss/base.scss Ændringer i Resources/app/storefront/src/scss/base.scss: 8 tilføjet, 0 fjernet
Ændringer i Resources/app/storefront/src/scss/base.scss: 8 tilføjet, 0 fjernet Linje før Linje efter Ændring Kode 1708 1708 margin: 8px 0 0; 1709 1709 font-size: 0.875rem; 1710 1710 } 1711 Tilføjet 1712 Tilføjet /* validiscan:focus-visible-styles */ 1713 Tilføjet /* Visible keyboard focus (WCAG 2.4.7): brand colour sw-color-brand-primary, 8.9:1 on #ffffff. */ 1714 Tilføjet :focus-visible { 1715 Tilføjet outline: 2px solid #6b3f1d; 1716 Tilføjet outline-offset: 2px; 1717 Tilføjet } 1718 Tilføjet /* /validiscan:focus-visible-styles */ -
En tab-rækkefølge, der følger siden remove-positive-tabindex Et
tabindexover 0 fjernes eller sættes til 0, så Tab-tasten følger sidens rækkefølge, medmindre skabelonens kode skriver det.Et
tabindexover 0 trækker et element forrest i tastaturrækkefølgen. Opskriften fjerner det fra links, knapper, formularfelter og andre elementer, der alligevel kan få fokus, og sætter det til 0 på andre elementer, så de stadig kan nås, mens Tab-tasten følger sidens rækkefølge. Ettabindex, som skabelonens kode skriver, overlades til et menneske. En scanning rapporterer en sådan tvunget rækkefølge to gange: gennem axe-core-reglentabindex, hvis fund får denne ændring, og gennem Validiscans kontrolvs-focus-order, hvis niveau er MANUAL, så dens fund kommer med vejledning.- Regler, den dækker
-
-
tabindexAUTO -
vs-focus-orderMANUAL
-
- Filtyper, den ændrer
-
.html.twig
removes tabindex="1" from the buy button; vs-focus-order and axe tabindex stop firing Eksempeldata Resources/views/storefront/page/product-detail/buy-widget.html.twig Ændringer i Resources/views/storefront/page/product-detail/buy-widget.html.twig: 1 tilføjet, 1 fjernet
Ændringer i Resources/views/storefront/page/product-detail/buy-widget.html.twig: 1 tilføjet, 1 fjernet Linje før Linje efter Ændring Kode 82 82 </div> 83 83 <div class="buy-widget-submit"> 84 84 <button class="btn btn-primary btn-buy" 85 Fjernet title="{{ 'detail.addProduct'|trans }}" tabindex="1"> 85 Tilføjet title="{{ 'detail.addProduct'|trans }}"> 86 86 {{ 'detail.addProduct'|trans }} 87 87 </button> 88 88 </div>
Zoom og klikflader
-
Zoom tilladt på mobilen meta-viewport-zoom Viewport-tagget mister
user-scalable=noog enhvermaximum-scaleunder 2, så besøgende kan forstørre teksten til mindst 200 % på en mobil.Opskriften fjerner
user-scalable=noog enhvermaximum-scaleunder 2 fra viewport-tagget i storefrontens skabeloner, som regel ilayout/meta.html.twig, så besøgende kan forstørre teksten til mindst 200 % på en mobil. For reglen for god praksismeta-viewport-largeer grænsen 5. De øvrige viewport-indstillinger forbliver, som de var. Hvis låsen var der for at hindre, at iOS zoomer ind på formularfelter, opnår man det med en skriftstørrelse på mindst 16 pixels i felterne, uden at zoom blokeres.- Regler, den dækker
-
-
meta-viewportAUTO -
meta-viewport-largeAUTO
-
- Filtyper, den ændrer
-
.html.twig
removes the zoom lock from the fixture theme and the rule stops firing Eksempeldata Resources/views/storefront/layout/meta.html.twig Ændringer i Resources/views/storefront/layout/meta.html.twig: 1 tilføjet, 1 fjernet
Ændringer i Resources/views/storefront/layout/meta.html.twig: 1 tilføjet, 1 fjernet Linje før Linje efter Ændring Kode 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 Fjernet <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"> 9 Tilføjet <meta name="viewport" content="width=device-width, initial-scale=1"> 10 10 {% endblock %} 11 11 12 12 {% block layout_head_meta_tags_general %} -
Større klikflader target-size-padding Knapper og links, som scanningen fandt mindre end 24 × 24 pixels, får den minimumsstørrelse, hvor opskriften kan udpege dem via deres klasse.
Knapper og links, som scanningen fandt mindre end 24 × 24 pixels, for eksempel ikoner i sidehovedet, knapper til antal eller farveprøver, får en minimumsstørrelse på 24 × 24 pixels. Minimumsstørrelsen tilføjes i den stilregel i temaet, der gjorde elementet lille, lige ved siden af den deklaration, der formindskede det. Så forbliver rækkefølgen af temaets stilregler den samme, og ikonerne inde i elementerne bevarer deres størrelse. Et betjeningselement, der er lille uden en sådan regel, får en minimumsstørrelse for sin klasse i hovedstilarket. Et betjeningselement, som opskriften ikke kan udpege via dets klasse, overlades til et menneske.
- Regler, den dækker
-
-
vs-target-sizeAUTO
-
- Filtyper, den ændrer
-
.scss
gives the header icons, steppers and swatches a 24px minimum; no page reports small targets Eksempeldata Resources/app/storefront/src/scss/_variant-broken.scss Ændringer i Resources/app/storefront/src/scss/_variant-broken.scss: 6 tilføjet, 2 fjernet
Ændringer i Resources/app/storefront/src/scss/_variant-broken.scss: 6 tilføjet, 2 fjernet Linje før Linje efter Ændring Kode 10 10 11 11 .header-actions-btn { 12 12 width: 18px; 13 Tilføjet min-width: 24px; 13 14 height: 18px; 14 Fjernet min-height: 0; 15 Tilføjet 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 Tilføjet min-width: 24px; 99 101 height: 18px; 102 Tilføjet 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 Tilføjet min-width: 24px; 106 110 height: 20px; 107 Fjernet min-height: 0; 111 Tilføjet min-height: 24px; 108 112 padding: 0; 109 113 } 110 114
Bevægelse, slideshows og lyd
-
Mindre bevægelse, når en besøgende beder om det reduced-motion-guard Når en besøgendes enhed beder om reduceret bevægelse, slutter de animationer og overgange, som stilark definerer, med det samme, og blød scrolling slås fra.
Når en besøgendes enhed er indstillet til at reducere bevægelse, får en blok i hovedstilarket animationer og overgange til at slutte med det samme og slår blød scrolling fra. Blokken gælder for hvert element på siden, så den også dækker animationer, som andre stilark definerer, herunder dem fra plugins. Hvor temaets storefront-script kun starter en timer, for eksempel et slideshows automatiske afspilning, når en autoplay-indstilling er sat, kontrollerer den betingelse nu også den besøgendes indstilling. Anden bevægelse, som et script starter, føres på listen til den, der gennemgår ændringen, og der gættes ikke.
- Regler, den dækker
-
-
vs-motionAUTO
-
- Filtyper, den ændrer
-
.js.scss
guards the pulsing badge and the slider autoplay; the animation stops under reduce Eksempeldata Resources/app/storefront/src/main.js Ændringer i Resources/app/storefront/src/main.js: 1 tilføjet, 1 fjernet
Ændringer i Resources/app/storefront/src/main.js: 1 tilføjet, 1 fjernet Linje før Linje efter Ændring Kode 139 139 }); 140 140 }); 141 141 142 Fjernet if (options.autoplay === true) { 142 Tilføjet 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 Ændringer i Resources/app/storefront/src/scss/base.scss: 14 tilføjet, 0 fjernet
Ændringer i Resources/app/storefront/src/scss/base.scss: 14 tilføjet, 0 fjernet Linje før Linje efter Ændring Kode 1708 1708 margin: 8px 0 0; 1709 1709 font-size: 0.875rem; 1710 1710 } 1711 Tilføjet 1712 Tilføjet /* validiscan:reduced-motion-guard */ 1713 Tilføjet /* Honour the visitor's reduced-motion setting: animations and transitions end at once, no smooth scrolling. */ 1714 Tilføjet @media (prefers-reduced-motion: reduce) { 1715 Tilføjet *, 1716 Tilføjet *::before, 1717 Tilføjet *::after { 1718 Tilføjet animation-duration: 0.01ms !important; 1719 Tilføjet animation-iteration-count: 1 !important; 1720 Tilføjet transition-duration: 0.01ms !important; 1721 Tilføjet scroll-behavior: auto !important; 1722 Tilføjet } 1723 Tilføjet } 1724 Tilføjet /* /validiscan:reduced-motion-guard */ -
En pauseknap til slideshows i bevægelse slider-pause-control Shopwares basisslider, der ligger bag CMS’ets billedslider, får en synlig, oversat knap til pause og afspilning.
Shopwares basisslider, den slider, der ligger bag CMS’ets billedslider, får ved siden af pilene til forrige og næste en synlig, oversat knap til pause og afspilning. En kodeblok i temaets storefront-script forbinder knappen med sliderens automatiske afspilning gennem Shopwares eget sliderplugin. Hvor temaet styrer den automatiske afspilning med sin egen timer, får timeren én linje, der springer et trin over, mens slideren er på pause. Knappen forbliver skjult, indtil scriptet har forbundet den, så den aldrig vises uden en automatisk afspilning, der kan sættes på pause. For besøgende, hvis enhed beder om reduceret bevægelse, starter slideren på pause. Slidere bygget med andre biblioteker overlades til et menneske.
- Regler, den dækker
-
-
vs-carouselAUTO
-
- Filtyper, den ændrer
-
.html.twig.js.json
adds a wired pause button to the hero slider; the carousel is no longer unstoppable Eksempeldata Resources/app/storefront/src/main.js Ændringer i Resources/app/storefront/src/main.js: 52 tilføjet, 0 fjernet
Ændringer i Resources/app/storefront/src/main.js: 52 tilføjet, 0 fjernet Linje før Linje efter Ændring Kode 142 142 if (options.autoplay === true) { 143 143 window.setInterval( 144 144 function () { 145 Tilføjet 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 Tilføjet 458 Tilføjet /* validiscan:slider-pause-control */ 459 Tilføjet /* 460 Tilføjet * Pause / play button of auto-advancing sliders (WCAG 2.2.2): wired to the 461 Tilføjet * slider's autoplay; sliders start paused when the visitor prefers reduced motion. 462 Tilføjet */ 463 Tilføjet (function sliderPauseControl() { 464 Tilføjet 'use strict'; 465 Tilføjet 466 Tilføjet function tinySlider(slider) { 467 Tilføjet const manager = window.PluginManager; 468 Tilføjet if (!manager || typeof manager.getPluginInstanceFromElement !== 'function') return null; 469 Tilføjet const plugin = manager.getPluginInstanceFromElement(slider, 'BaseSlider'); 470 Tilføjet return plugin && plugin._slider ? plugin._slider : null; 471 Tilføjet } 472 Tilføjet 473 Tilføjet function autoplays(slider) { 474 Tilføjet try { 475 Tilføjet const options = JSON.parse(slider.getAttribute('data-base-slider-options') || '{}') || {}; 476 Tilføjet return Boolean(options.slider && options.slider.autoplay); 477 Tilføjet } catch { 478 Tilføjet return false; 479 Tilføjet } 480 Tilføjet } 481 Tilføjet 482 Tilføjet function init() { 483 Tilføjet const reduceMotion = 484 Tilføjet window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches; 485 Tilføjet document.querySelectorAll('[data-slider-pause]').forEach(function (button) { 486 Tilføjet const slider = button.closest('[data-base-slider]'); 487 Tilføjet if (!slider || !autoplays(slider)) return; 488 Tilføjet 489 Tilføjet function setPaused(paused) { 490 Tilføjet slider.setAttribute('data-autoplay-paused', paused ? 'true' : 'false'); 491 Tilføjet button.textContent = button.getAttribute(paused ? 'data-label-play' : 'data-label-pause'); 492 Tilføjet const instance = tinySlider(slider); 493 Tilføjet if (instance) instance[paused ? 'pause' : 'play'](); 494 Tilføjet } 495 Tilføjet 496 Tilføjet button.hidden = false; 497 Tilføjet button.addEventListener('click', function () { 498 Tilføjet setPaused(slider.getAttribute('data-autoplay-paused') !== 'true'); 499 Tilføjet }); 500 Tilføjet if (reduceMotion) setPaused(true); 501 Tilføjet }); 502 Tilføjet } 503 Tilføjet 504 Tilføjet if (document.readyState === 'complete') init(); 505 Tilføjet else window.addEventListener('load', init); 506 Tilføjet })(); 507 Tilføjet /* /validiscan:slider-pause-control */ Resources/snippet/de_DE/kaffeekontor-nord.de-DE.json Ændringer i Resources/snippet/de_DE/kaffeekontor-nord.de-DE.json: 6 tilføjet, 0 fjernet
Ændringer i Resources/snippet/de_DE/kaffeekontor-nord.de-DE.json: 6 tilføjet, 0 fjernet Linje før Linje efter Ændring Kode 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 Tilføjet }, 197 Tilføjet "a11y": { 198 Tilføjet "slider": { 199 Tilføjet "pause": "Diashow anhalten", 200 Tilføjet "play": "Diashow abspielen" 201 Tilføjet } 196 202 } 197 203 } Resources/snippet/en_GB/kaffeekontor-nord.en-GB.json Ændringer i Resources/snippet/en_GB/kaffeekontor-nord.en-GB.json: 6 tilføjet, 0 fjernet
Ændringer i Resources/snippet/en_GB/kaffeekontor-nord.en-GB.json: 6 tilføjet, 0 fjernet Linje før Linje efter Ændring Kode 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 Tilføjet }, 197 Tilføjet "a11y": { 198 Tilføjet "slider": { 199 Tilføjet "pause": "Pause slideshow", 200 Tilføjet "play": "Play slideshow" 201 Tilføjet } 196 202 } 197 203 } Resources/views/storefront/element/cms-element-image-slider.html.twig Ændringer i Resources/views/storefront/element/cms-element-image-slider.html.twig: 1 tilføjet, 0 fjernet
Ændringer i Resources/views/storefront/element/cms-element-image-slider.html.twig: 1 tilføjet, 0 fjernet Linje før Linje efter Ændring Kode 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 Tilføjet <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> -
Ingen blinkende eller rullende tekst remove-blink-marquee
<blink>- og<marquee>-elementer i Twig-skabelonerne bliver til statiske elementer med samme indhold, klasser og id’er, så ingen tekst bevæger sig af sig selv.<blink>- og<marquee>-elementer i Twig-skabelonerne bliver til statiske elementer med samme indhold, klasser og id’er: en<span>for blink, en<div>for marquee eller en<span>, hvor marqueen sidder inde i et afsnit eller et lignende tekstelement. Marqueens rulleindstillinger fjernes, så ingen tekst bevæger sig af sig selv.- Regler, den dækker
-
-
blinkAUTO -
marqueeAUTO
-
- Filtyper, den ændrer
-
.html.twig
replaces a seeded marquee and blink in the top bar; axe no longer reports them Eksempeldata Resources/views/storefront/layout/header/top-bar.html.twig Ændringer i Resources/views/storefront/layout/header/top-bar.html.twig: 2 tilføjet, 2 fjernet
Ændringer i Resources/views/storefront/layout/header/top-bar.html.twig: 2 tilføjet, 2 fjernet Linje før Linje efter Ændring Kode 4 4 {% block layout_header_top_bar_usp %} 5 5 <p class="top-bar-usp"> 6 6 {% sw_icon 'checkmark' style { size: 'xs' } %} 7 Fjernet <marquee class="top-bar-marquee" behavior="scroll" scrollamount="4"><span>{{ 'header.topBarUsp'|trans }}</span></marquee> 7 Tilføjet <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 Fjernet <blink class="top-bar-blink">{{ 'header.topBarHelp'|trans }}</blink> 16 Tilføjet <span class="top-bar-blink">{{ 'header.topBarHelp'|trans }}</span> 17 17 </a> 18 18 </li> 19 19 </ul> -
Ingen lyd, der starter af sig selv mute-autoplay En video, der afspilles af sig selv, gøres lydløs, og lyd starter ikke længere af sig selv, undtagen automatisk afspilning fra skabelonkode eller et script og afspillere i indlejrede rammer; på Shopware bruges opskriften ikke til fund fra
vs-media.En video, der afspilles af sig selv, får
mutedogplaysinline, så den fortsætter med at spille lydløst, som en baggrundsvideo gør, og afspilles inde på siden i Safari på mobilen i stedet for at åbne afspilleren i fuld skærm. Lyd starter ikke længere af sig selv; de besøgende starter den selv. Automatisk afspilning, som skabelonkode eller et script sætter, og afspillere i indlejrede rammer overlades til et menneske. I en Validiscan-scanning rapporteres lyd, der starter af sig selv, af Validiscans mediekontrolvs-media, som erstatter axe-core-reglenno-autoplay-audio.vs-media, som også dækker undertekster og transskriptioner, har niveau MANUAL, så et sådant fund på Shopware kommer med vejledning i stedet for denne ændring.- Regler, den dækker
-
-
no-autoplay-audioAUTO kontrolleres via vs-media -
vs-mediaMANUAL
-
- Filtyper, den ændrer
-
.html.twig
mutes a seeded autoplaying background video; vs-media no longer reports autoplay Eksempeldata Resources/views/storefront/block/cms-block-video.html.twig Ændringer i Resources/views/storefront/block/cms-block-video.html.twig: 1 tilføjet, 1 fjernet
Ændringer i Resources/views/storefront/block/cms-block-video.html.twig: 1 tilføjet, 1 fjernet Linje før Linje efter Ændring Kode 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 Fjernet <video class="cms-video" autoplay loop preload="none" width="1280" height="720" poster="{{ block.posterUrl }}"> 12 Tilføjet <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>
Formularer, kurven og indlejret indhold
-
Etiketter knyttet til deres felter label-association Et felt, hvis etikettekst allerede står på siden lige før feltet, bliver knyttet til den tekst.
Et formularfelt, hvis etikettekst allerede står på siden lige før feltet, bliver knyttet til den tekst. Et
<label>udenforfår enfor-attribut, der peger på feltet. Et tekstelement, som temaet via sin klasse markerer som titel eller etiket, for eksempel navnet på en variantgruppe på en produktside, bliver feltets<label>og beholder sine klasser og sin egen linje. Skærmlæsere læser så etiketten op, når feltet får fokus. Et felt, der kun har en pladsholdertekst, overlades til et menneske, fordi det er en beslutning om indhold at skrive en etiket.- Regler, den dækker
-
-
labelAUTO kontrolleres via vs-forms-ecommerce -
select-nameASSISTED -
vs-forms-ecommerceAUTO
-
- Filtyper, den ændrer
-
.html.twig
turns the variant group titles into labels of their selects; select-name no longer fires Eksempeldata Resources/views/storefront/page/product-detail/configurator.html.twig Ændringer i Resources/views/storefront/page/product-detail/configurator.html.twig: 1 tilføjet, 1 fjernet
Ændringer i Resources/views/storefront/page/product-detail/configurator.html.twig: 1 tilføjet, 1 fjernet Linje før Linje efter Ændring Kode 13 13 {% for group in product.configurator %} 14 14 {% if group.display == 'select' %} 15 15 <div class="product-detail-configurator-group"> 16 Fjernet <div class="product-detail-configurator-group-title">{{ group.name }}</div> 16 Tilføjet <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) %} -
Konto-, adresse- og kontaktfelter, som browsere kan udfylde autocomplete-tokens Felter, der spørger efter kundens egne oplysninger, for eksempel ved registrering, adresse og login, får den
autocomplete-værdi, der svarer til det, de spørger efter, medmindre skabelonkode skriver den.Felter, der spørger efter kundens egne oplysninger, for eksempel i formularerne til registrering, adresse, login, kontakt og nyhedsbrev, får den
autocomplete-værdi, der svarer til det, de spørger efter, for eksempel e-mail, for- og efternavn, postnummer, telefonnummer eller adgangskode. Værdien udledes af feltets type, navn, id, etiket og pladsholdertekst. Adgangskoder fårnew-passwordi registreringsformularer ogcurrent-passwordellers. Felter til søgning, rabatkode, antal, captcha og beskeder bliver, som de er, og en værdi, som skabelonkode skriver, overlades til et menneske. Browsere kan så udfylde felterne, og hjælpemidler kan se, hvad hvert felt skal bruges til.- Regler, den dækker
-
-
autocomplete-validAUTO kontrolleres via vs-forms-ecommerce -
vs-forms-ecommerceAUTO
-
- Filtyper, den ændrer
-
.html.twig
adds tokens to the register, address, login, contact and newsletter fields; no autocomplete hits remain Eksempeldata Resources/views/storefront/component/account/login.html.twig Ændringer i Resources/views/storefront/component/account/login.html.twig: 1 tilføjet, 1 fjernet
Ændringer i Resources/views/storefront/component/account/login.html.twig: 1 tilføjet, 1 fjernet Linje før Linje efter Ændring Kode 19 19 name="username" 20 20 placeholder="{{ 'account.loginMailPlaceholder'|trans }}" 21 21 required 22 Fjernet autocomplete="off"> 22 Tilføjet autocomplete="email"> 23 23 </div> 24 24 25 25 <div class="form-group"> Resources/views/storefront/component/account/register.html.twig Ændringer i Resources/views/storefront/component/account/register.html.twig: 8 tilføjet, 4 fjernet
Ændringer i Resources/views/storefront/component/account/register.html.twig: 8 tilføjet, 4 fjernet Linje før Linje efter Ændring Kode 33 33 id="{{ formId }}FirstName" 34 34 name="firstName" 35 35 placeholder="{{ 'account.firstNamePlaceholder'|trans }}" 36 Fjernet required> 36 Tilføjet required 37 Tilføjet 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 Fjernet required> 45 Tilføjet required 46 Tilføjet 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 Fjernet required> 57 Tilføjet required 58 Tilføjet 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 Fjernet required> 68 Tilføjet required 69 Tilføjet 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 Ændringer i Resources/views/storefront/component/address/address-form.html.twig: 8 tilføjet, 4 fjernet
Ændringer i Resources/views/storefront/component/address/address-form.html.twig: 8 tilføjet, 4 fjernet Linje før Linje efter Ændring Kode 14 14 id="{{ prefix }}AddressStreet" 15 15 name="{{ prefix }}[street]" 16 16 placeholder="{{ 'address.streetPlaceholder'|trans }}" 17 Fjernet required> 17 Tilføjet required 18 Tilføjet 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 Fjernet required> 30 Tilføjet required 31 Tilføjet 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 Fjernet required> 42 Tilføjet required 43 Tilføjet 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 Fjernet required> 53 Tilføjet required 54 Tilføjet 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 Ændringer i Resources/views/storefront/element/cms-element-form.html.twig: 4 tilføjet, 4 fjernet
Ændringer i Resources/views/storefront/element/cms-element-form.html.twig: 4 tilføjet, 4 fjernet Linje før Linje efter Ændring Kode 18 18 </select> 19 19 </div> 20 20 <div class="form-group col-md-4"> 21 Fjernet <input type="text" class="form-control" id="contactFormFirstName" name="firstName" placeholder="{{ 'account.firstNamePlaceholder'|trans }}" required> 21 Tilføjet <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 Fjernet <input type="text" class="form-control" id="contactFormLastName" name="lastName" placeholder="{{ 'account.lastNamePlaceholder'|trans }}" required> 24 Tilføjet <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 Fjernet <input type="email" class="form-control" id="contactFormMail" name="email" placeholder="{{ 'account.emailPlaceholder'|trans }}" required> 31 Tilføjet <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 Fjernet <input type="tel" class="form-control" id="contactFormPhone" name="phone"> 35 Tilføjet <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 Ændringer i Resources/views/storefront/layout/footer/footer.html.twig: 2 tilføjet, 1 fjernet
Ændringer i Resources/views/storefront/layout/footer/footer.html.twig: 2 tilføjet, 1 fjernet Linje før Linje efter Ændring Kode 62 62 id="footerNewsletterMail" 63 63 class="form-control" 64 64 placeholder="{{ 'footer.newsletterPlaceholder'|trans }}" 65 Fjernet required> 65 Tilføjet required 66 Tilføjet 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"> -
Ændringer i pris, lagerstatus og kurv bliver oplæst live-region-cart-variant Prisen, lagerstatussen eller kurvens samlede beløb, som storefront-scriptet opdaterer på stedet, bliver live-områder, som skærmlæsere læser op uden at afbryde, medmindre scriptet erstatter selve elementet.
De dele af en side, som storefront-scriptet opdaterer på stedet, for eksempel prisen, når en kunde vælger en variant, lagerstatussen eller kurvens samlede beløb, bliver live-områder af typen »polite«. Skærmlæsere oplæser så den nye værdi én gang og i sin helhed uden at afbryde. Hvor et script erstatter selve elementet i stedet for dets indhold, ville et live-område ikke virke, så opskriften overlader det element til et menneske.
- Regler, den dækker
-
-
vs-live-updatesAUTO
-
- Filtyper, den ændrer
-
.html.twig
makes the variant price and the cart totals polite live regions; the updates are announced Eksempeldata Resources/views/storefront/page/checkout/cart/index.html.twig Ændringer i Resources/views/storefront/page/checkout/cart/index.html.twig: 2 tilføjet, 2 fjernet
Ændringer i Resources/views/storefront/page/checkout/cart/index.html.twig: 2 tilføjet, 2 fjernet Linje før Linje efter Ændring Kode 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 Fjernet <div class="line-item-total-price"> 62 Tilføjet <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 Fjernet <div class="checkout-aside-summary-totals" data-shipping-threshold="{{ shop.shippingThreshold }}" data-shipping-costs="{{ shop.shippingCosts }}"> 91 Tilføjet <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 Ændringer i Resources/views/storefront/page/product-detail/buy-widget.html.twig: 1 tilføjet, 1 fjernet
Ændringer i Resources/views/storefront/page/product-detail/buy-widget.html.twig: 1 tilføjet, 1 fjernet Linje før Linje efter Ændring Kode 17 17 {% endblock %} 18 18 19 19 {% block buy_widget_price %} 20 Fjernet <div class="product-detail-price-container"> 20 Tilføjet <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> -
Titler til indlejrede kort og videoer iframe-title En indlejret ramme uden titel får en oversat titel, der siger, hvad den viser, hvor koden afslører det.
En indlejret ramme uden titel, for eksempel et kort eller en YouTube- eller Vimeo-video, får en oversat titel fra temaets snippet-filer, der siger, hvad den viser. Opskriften læser, hvad rammen viser, ud fra dens adresse, dens klasse og navn eller skabelonen omkring den. En ramme, hvis indhold koden ikke afslører, får ingen titel af opskriften, fordi en opfundet titel er værre end ingen.
- Regler, den dækker
-
-
frame-titleAUTO
-
- Filtyper, den ændrer
-
.html.twig.json
titles the contact map frame through the snippets; frame-title no longer fires Eksempeldata Resources/snippet/de_DE/kaffeekontor-nord.de-DE.json Ændringer i Resources/snippet/de_DE/kaffeekontor-nord.de-DE.json: 5 tilføjet, 0 fjernet
Ændringer i Resources/snippet/de_DE/kaffeekontor-nord.de-DE.json: 5 tilføjet, 0 fjernet Linje før Linje efter Ændring Kode 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 Tilføjet }, 197 Tilføjet "a11y": { 198 Tilføjet "iframe": { 199 Tilføjet "map": "Karte" 200 Tilføjet } 196 201 } 197 202 } Resources/snippet/en_GB/kaffeekontor-nord.en-GB.json Ændringer i Resources/snippet/en_GB/kaffeekontor-nord.en-GB.json: 5 tilføjet, 0 fjernet
Ændringer i Resources/snippet/en_GB/kaffeekontor-nord.en-GB.json: 5 tilføjet, 0 fjernet Linje før Linje efter Ændring Kode 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 Tilføjet }, 197 Tilføjet "a11y": { 198 Tilføjet "iframe": { 199 Tilføjet "map": "Map" 200 Tilføjet } 196 201 } 197 202 } Resources/views/storefront/block/cms-block-map.html.twig Ændringer i Resources/views/storefront/block/cms-block-map.html.twig: 2 tilføjet, 1 fjernet
Ændringer i Resources/views/storefront/block/cms-block-map.html.twig: 2 tilføjet, 1 fjernet Linje før Linje efter Ændring Kode 11 11 <iframe class="cms-map-frame" 12 12 src="{{ url('/widgets/cms/map') }}" 13 13 width="1280" 14 Fjernet height="360"></iframe> 14 Tilføjet height="360" 15 Tilføjet 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>
Kontrast, billeder og betjeningselementer, der kræver en vurdering
Tekstkontrast, tekstalternativer til billeder og navne til betjeningselementer uden navn kræver som regel en vurdering: hvilken farve der passer til dit brand, hvilke ord der beskriver et billede. De regler, der rapporterer dem, har niveau ASSISTED, som listerne herunder viser. For et fund på en ASSISTED-regel udarbejder AI kun et udkast til en ændring, hvis du har sagt ja til AI-udkast, og Validiscan gennemgår hver ændring, før den leveres.
De fire opskrifter herunder er ikke standardrettelsen for nogen regel. Hver af dem dækker kun de snævre tilfælde, hvor temaets kode alene beviser, hvad ændringen skal være. To af dem, button-semantics og icon-accessible-name, dækker også slideshow-kontrollen vs-carousel, som har niveau AUTO: I et projekt prøver rettelsesmotoren dem på dens fund, når opskriften med pauseknappen ovenfor ikke kan rette dem. De to andre dækker kun regler på niveau ASSISTED.
-
Tekstfarver med tilstrækkelig kontrast contrast-tokens En tekstfarve, der ikke består kontrastkontrollen og er defineret ét sted, ændres til den nærmeste nuance i samme farvetone med den krævede kontrast; anvendes ikke i et projekt.
Når en tekst ikke består kontrastkontrollen, og dens farve er defineret ét sted i temaet, ændres det sted til den nærmeste nuance i samme farvetone, som opnår den krævede kontrast, så designet forbliver genkendeligt. Ét sted kan være et farvefelt i
theme.jsonsammen med den SCSS-variabel, der gentager det, en SCSS-variabel eller en CSS-variabel, der kun bruges til tekst, eller en enkeltcolor-deklaration. En farve, der bruges flere steder eller også som baggrund eller kant, og Shopwares centrale farvefelter til brandet, kanter, baggrunde, statusmeddelelser og købsknappen overlades til et menneske. En farve, der er gemt i temaindstillingerne i Shopware-administrationen, tilsidesættertheme.json: Hvis den er ændret dér, skal den ændres dér også. Reglencolor-contrasthar niveau ASSISTED, så i et projekt følger et kontrastfund ASSISTED-forløbet, og denne opskrift anvendes ikke på det.- Regler, den dækker
-
-
color-contrastASSISTED
-
- Filtyper, den ændrer
-
.scss
darkens the unit price colour to 4.5:1 with the same hue; axe clears it on both pages Eksempeldata Resources/app/storefront/src/scss/_variant-broken.scss Ændringer i Resources/app/storefront/src/scss/_variant-broken.scss: 1 tilføjet, 1 fjernet
Ændringer i Resources/app/storefront/src/scss/_variant-broken.scss: 1 tilføjet, 1 fjernet Linje før Linje efter Ændring Kode 45 45 /* Light grey unit prices, 3.1:1 (color-contrast). */ 46 46 .product-price-unit, 47 47 .product-detail-price-unit { 48 Fjernet color: #929292; 48 Tilføjet color: #757575; 49 49 } 50 50 51 51 /* Fixed two-line product names (vs-text-spacing). */ -
Dekorative billeder skjult for skærmlæsere decorative-image-alt Kun billeder, som skabelonen beviser er dekorative, får et tomt
altelleraria-hidden; anvendes ikke i et projekt.Et billede markeres kun som dekorativt, når skabelonen beviser, at det ikke tilføjer noget: Det sidder i et link eller en knap, der har navn på anden måde, det er et ikon ved siden af sin egen tekstetiket, eller det er en afstandsholder eller en skillelinje. Et
<img>får et tomtalt, et billede, der udskrives med Shopwaressw_thumbnails-tag, får et tomtalti sine attributter, og SVG-ikoner fåraria-hidden="true", så skærmlæsere springer dem over i stedet for at læse et filnavn op. Ethvert andet billede er indhold, for eksempel betalingslogoerne i en sidefod, og dets tekstalternativ kræver ord, som et menneske vælger. De regler, denne opskrift dækker, har niveau ASSISTED, så i et projekt følger deres fund ASSISTED-forløbet, og denne opskrift anvendes ikke på dem.- Regler, den dækker
-
-
image-altASSISTED -
role-img-altASSISTED -
svg-img-altASSISTED
-
- Filtyper, den ændrer
-
.html.twig
marks a seeded phone icon inside the hotline link decorative; image-alt stops firing there Eksempeldata Resources/views/storefront/layout/footer/footer.html.twig Ændringer i Resources/views/storefront/layout/footer/footer.html.twig: 1 tilføjet, 1 fjernet
Ændringer i Resources/views/storefront/layout/footer/footer.html.twig: 1 tilføjet, 1 fjernet Linje før Linje efter Ændring Kode 9 9 <div class="footer-column-content"> 10 10 <p class="footer-contact-hotline"> 11 11 {{ 'footer.serviceHotlineText'|trans }} 12 Fjernet <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 Tilføjet <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"> -
Navne til knapper og links, der kun består af et ikon icon-accessible-name Knapper og links, der kun viser et ikon, får et oversat navn, der siger, hvad de gør, hvor koden afslører deres formål; i et projekt prøves opskriften på de slideshowkontroller, som
vs-carouselrapporterer.Knapper og links, der kun viser et ikon, for eksempel søgning, kurv, konto, logolinket, pile i slidere, knapper til antal og cookievalg, får en oversat
aria-label, der siger, hvad de gør. Formålet udledes af betjeningselementets klasser, dets linkmål, ikonet inde i det og den komponent, der omgiver det. Et betjeningselement, hvis formål koden ikke afslører, for eksempel et link til et socialt medie, hvis netværk er gemt som data, overlades til et menneske, fordi et opfundet navn er værre end intet. I et projekt prøves denne opskrift på de slideshowkontroller, somvs-carouselrapporterer; andre betjeningselementer, der kun består af et ikon, rapporteres af regler på niveau ASSISTED og følger ASSISTED-forløbet.- Regler, den dækker
-
-
button-nameASSISTED -
link-nameASSISTED -
vs-carouselAUTO -
vs-cookie-bannerASSISTED
-
- Filtyper, den ændrer
-
.html.twig.json
names every icon-only button of the home, product and cart pages; button-name no longer fires Eksempeldata Resources/snippet/de_DE/kaffeekontor-nord.de-DE.json Ændringer i Resources/snippet/de_DE/kaffeekontor-nord.de-DE.json: 12 tilføjet, 0 fjernet
Ændringer i Resources/snippet/de_DE/kaffeekontor-nord.de-DE.json: 12 tilføjet, 0 fjernet Linje før Linje efter Ændring Kode 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 Tilføjet }, 197 Tilføjet "a11y": { 198 Tilføjet "control": { 199 Tilføjet "search": "Suchen", 200 Tilføjet "previousSlide": "Vorherige Folie", 201 Tilføjet "nextSlide": "Nächste Folie", 202 Tilføjet "cookieSettings": "Cookie-Einstellungen", 203 Tilføjet "acceptCookies": "Alle Cookies akzeptieren", 204 Tilføjet "decreaseQuantity": "Menge verringern", 205 Tilføjet "increaseQuantity": "Menge erhöhen", 206 Tilføjet "removeFromCart": "Aus dem Warenkorb entfernen" 207 Tilføjet } 196 208 } 197 209 } Resources/snippet/en_GB/kaffeekontor-nord.en-GB.json Ændringer i Resources/snippet/en_GB/kaffeekontor-nord.en-GB.json: 12 tilføjet, 0 fjernet
Ændringer i Resources/snippet/en_GB/kaffeekontor-nord.en-GB.json: 12 tilføjet, 0 fjernet Linje før Linje efter Ændring Kode 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 Tilføjet }, 197 Tilføjet "a11y": { 198 Tilføjet "control": { 199 Tilføjet "search": "Search", 200 Tilføjet "previousSlide": "Previous slide", 201 Tilføjet "nextSlide": "Next slide", 202 Tilføjet "cookieSettings": "Cookie settings", 203 Tilføjet "acceptCookies": "Accept all cookies", 204 Tilføjet "decreaseQuantity": "Decrease quantity", 205 Tilføjet "increaseQuantity": "Increase quantity", 206 Tilføjet "removeFromCart": "Remove from cart" 207 Tilføjet } 196 208 } 197 209 } Resources/views/storefront/element/cms-element-image-gallery.html.twig Ændringer i Resources/views/storefront/element/cms-element-image-gallery.html.twig: 2 tilføjet, 2 fjernet
Ændringer i Resources/views/storefront/element/cms-element-image-gallery.html.twig: 2 tilføjet, 2 fjernet Linje før Linje efter Ændring Kode 31 31 32 32 {% if media|length > 1 %} 33 33 <div class="gallery-slider-controls"> 34 Fjernet <button type="button" class="base-slider-controls-prev gallery-slider-controls-prev" data-gallery-prev> 34 Tilføjet <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 Fjernet <button type="button" class="base-slider-controls-next gallery-slider-controls-next" data-gallery-next> 37 Tilføjet <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 Ændringer i Resources/views/storefront/element/cms-element-image-slider.html.twig: 2 tilføjet, 2 fjernet
Ændringer i Resources/views/storefront/element/cms-element-image-slider.html.twig: 2 tilføjet, 2 fjernet Linje før Linje efter Ændring Kode 46 46 47 47 {% block element_image_slider_controls %} 48 48 <div class="image-slider-controls-container"> 49 Fjernet <button type="button" class="base-slider-controls-prev image-slider-controls-btn" data-slide-prev> 49 Tilføjet <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 Fjernet <button type="button" class="base-slider-controls-next image-slider-controls-btn" data-slide-next> 57 Tilføjet <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 Ændringer i Resources/views/storefront/layout/cookie/cookie-permission.html.twig: 2 tilføjet, 2 fjernet
Ændringer i Resources/views/storefront/layout/cookie/cookie-permission.html.twig: 2 tilføjet, 2 fjernet Linje før Linje efter Ændring Kode 22 22 </p> 23 23 </div> 24 24 <div class="col-auto cookie-permission-actions"> 25 Fjernet <button type="button" class="btn cookie-permission-icon-btn js-cookie-configuration-toggle">{% sw_icon 'settings' %}</button> 26 Fjernet <button type="button" class="btn btn-primary cookie-permission-icon-btn js-cookie-accept-all-button">{% sw_icon 'checkmark' %}</button> 25 Tilføjet <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 Tilføjet <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 Ændringer i Resources/views/storefront/layout/header/search.html.twig: 1 tilføjet, 1 fjernet
Ændringer i Resources/views/storefront/layout/header/search.html.twig: 1 tilføjet, 1 fjernet Linje før Linje efter Ændring Kode 13 13 autocomplete="off" 14 14 autocapitalize="off" 15 15 placeholder="{{ 'header.searchPlaceholder'|trans }}" value="{{ page.searchTerm }}"> 16 Fjernet <button type="submit" class="btn header-search-btn"> 16 Tilføjet <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 Ændringer i Resources/views/storefront/page/checkout/cart/index.html.twig: 3 tilføjet, 3 fjernet
Ændringer i Resources/views/storefront/page/checkout/cart/index.html.twig: 3 tilføjet, 3 fjernet Linje før Linje efter Ændring Kode 39 39 </div> 40 40 <div class="line-item-quantity"> 41 41 <div class="input-group quantity-selector-group" data-quantity-selector="true"> 42 Fjernet <button type="button" class="btn btn-outline-light btn-minus js-btn-minus"> 42 Tilføjet <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 Fjernet <button type="button" class="btn btn-outline-light btn-plus js-btn-plus"> 53 Tilføjet <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 Fjernet <button type="button" class="btn btn-light btn-sm line-item-remove-button"> 67 Tilføjet <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 Ændringer i Resources/views/storefront/page/product-detail/buy-widget.html.twig: 2 tilføjet, 2 fjernet
Ændringer i Resources/views/storefront/page/product-detail/buy-widget.html.twig: 2 tilføjet, 2 fjernet Linje før Linje efter Ændring Kode 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 Fjernet <button type="button" class="btn btn-outline-light btn-minus js-btn-minus"> 67 Tilføjet <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 Fjernet <button type="button" class="btn btn-outline-light btn-plus js-btn-plus"> 78 Tilføjet <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 Eksempeldata Resources/snippet/de_DE/kaffeekontor-nord.de-DE.json Ændringer i Resources/snippet/de_DE/kaffeekontor-nord.de-DE.json: 6 tilføjet, 0 fjernet
Ændringer i Resources/snippet/de_DE/kaffeekontor-nord.de-DE.json: 6 tilføjet, 0 fjernet Linje før Linje efter Ændring Kode 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 Tilføjet }, 197 Tilføjet "a11y": { 198 Tilføjet "control": { 199 Tilføjet "home": "Zur Startseite", 200 Tilføjet "account": "Ihr Konto" 201 Tilføjet } 196 202 } 197 203 } Resources/snippet/en_GB/kaffeekontor-nord.en-GB.json Ændringer i Resources/snippet/en_GB/kaffeekontor-nord.en-GB.json: 6 tilføjet, 0 fjernet
Ændringer i Resources/snippet/en_GB/kaffeekontor-nord.en-GB.json: 6 tilføjet, 0 fjernet Linje før Linje efter Ændring Kode 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 Tilføjet }, 197 Tilføjet "a11y": { 198 Tilføjet "control": { 199 Tilføjet "home": "Go to the homepage", 200 Tilføjet "account": "Your account" 201 Tilføjet } 196 202 } 197 203 } Resources/views/storefront/layout/header/actions.html.twig Ændringer i Resources/views/storefront/layout/header/actions.html.twig: 2 tilføjet, 1 fjernet
Ændringer i Resources/views/storefront/layout/header/actions.html.twig: 2 tilføjet, 1 fjernet Linje før Linje efter Ændring Kode 3 3 {% block layout_header_actions_account %} 4 4 <div class="header-account"> 5 5 <a href="{{ url('/account/login') }}" 6 Fjernet class="btn account-menu-btn header-actions-btn"> 6 Tilføjet class="btn account-menu-btn header-actions-btn" 7 Tilføjet 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 Ændringer i Resources/views/storefront/layout/header/logo.html.twig: 1 tilføjet, 1 fjernet
Ændringer i Resources/views/storefront/layout/header/logo.html.twig: 1 tilføjet, 1 fjernet Linje før Linje efter Ændring Kode 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 Fjernet <a class="header-logo-main-link" href="{{ url('/') }}"> 5 Tilføjet <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') }}"
Detaljer: niveauerne, testtemaet, kontrollen af hver ændring og tekst på din webshops sprog
En opskrift er en deterministisk ændring for én slags fejl: Den samme kode får altid den samme ændring. Validiscan har 20 opskrifter til Shopware-temaer. Hver af dem foretager kun en ændring, hvor temaets kode viser, hvad den rigtige ændring er. Hvor den ikke gør det, ændrer opskriften intet. Den gætter ikke.
Under hver opskrift finder du de regler, den dækker, med hver regels niveau i Validiscans regelkatalog for Shopware. AUTO betyder, at en opskrift er reglens standardrettelse. ASSISTED betyder, at rettelsen kræver en vurdering, så en ændring udarbejdes som udkast og gennemgås derefter. MANUAL betyder, at reglen kræver en persons beslutning og kommer med vejledning, ikke med en kodeændring. I et projekt anvendes opskrifter på fund af regler på niveau AUTO. Hvor en opskrift også angiver en regel på niveau ASSISTED eller MANUAL, følger et fund af den regel i stedet ASSISTED- eller MANUAL-forløbet. En regel, der kontrolleres via en anden kontrol, køres ikke selvstændigt i en scanning; den anden kontrol rapporterer den samme fejl.
Filtyperne og før-og-efter-visningen for hver opskrift stammer fra Validiscans egne tests. De kører på Validiscans Shopware-testtema, et temaplugin bygget på standard-storefronten i Shopware 6, hvor der med vilje er lagt tilgængelighedsfejl ind. Hver test gengiver temaets skabeloner som sider før og efter ændringen og kører den samme regel på begge: Fejlen skal rapporteres før og ikke længere efter, og ændringen må ikke give en ny fejl for den regel. Siderne gengives af en testrenderer, ikke af en fuld Shopware-installation, og dit temas filer ser anderledes ud.
Før Validiscan gennemgår en ændring, kontrolleres hver ændret fil. Twig-skabeloner læses af en parser, der kender Shopwares egne tags, for eksempel sw_extends og sw_include; de kompileres eller køres aldrig. Stilark får en strukturkontrol, snippet-filer og theme.json læses som JSON, og JavaScript får en syntakskontrol.
Når en opskrift tilføjer synlig tekst eller et navn, for eksempel ordene i et spring over-link eller navnet på en ikonknap, bruger den en snippet i skabelonen. Teksten lægges i temaets engelske snippet-fil, som opskriften opretter, hvis temaet ikke har en, og i dets tyske snippet-fil, hvor temaet har en. Snippets, der allerede findes, beholder deres tekst. Tekst på webshoppens andre sprog tilføjes ikke.
Hvad forbliver på niveau MANUAL på Shopware?
Fejl, der kræver en beslutning om indhold eller adfærd, som en fast kodeændring ikke kan træffe, for eksempel undertekster og transskriptioner til dine videoer og din lyd, forbliver på niveau MANUAL på Shopware. For et fund på en MANUAL-regel giver Validiscan vejledning i, hvordan det rettes, ikke en ændring af din kode.
Reglerne herunder køres i scanninger og har niveau MANUAL på Shopware.
-
meta-refreshForsinket genindlæsning under 20 timer må ikke bruges -
nested-interactiveInteraktive betjeningselementer må ikke være indlejret i hinanden -
scrollable-region-focusableScrollbare områder skal kunne nås med tastaturet -
server-side-image-mapServerside-billedkort må ikke bruges -
vs-keyboard-trapTastaturfokus må aldrig sidde fast -
vs-focus-orderFokusrækkefølgen skal følge den visuelle rækkefølge -
vs-draggingElementer, der kun kan betjenes ved at trække, skal have et alternativ med et enkelt klik eller tryk -
vs-mediaVideo skal have undertekster, lyd skal have en transskription, og intet må afspille lyd automatisk -
vs-documentsLinkede dokumenter skal gennemgås manuelt for tilgængelighed
Detaljer: hvad et fund på niveau MANUAL får, og hvad et projekt ikke omfatter
For et fund på en MANUAL-regel giver Validiscan vejledning i, hvordan det rettes, ikke en ændring af din kode. Disse fejl kræver en beslutning om indhold eller adfærd, som en fast kodeændring ikke kan træffe, for eksempel undertekster og transskriptioner til dine videoer og din lyd, en vej ud af en widget, hvor tastaturfokus sidder fast, eller en anden måde at bruge et betjeningselement på, som kun virker ved at trække.
Arbejdet med fund på niveau MANUAL, der kræver dine egne beslutninger om indhold, er ikke en del af et projekt, og det samme gælder PDF-filer. Hvad scanningen tester automatisk, og hvad der kontrolleres ved manuel gennemgang
Hvad stiller du til rådighed?
Du sørger for tilladelse til en fuld scanning, én vej ind i dit temaplugin, dit svar om AI-udkast til ASSISTED-rettelser, en udvikler, der gennemgår ændringerne, bygger og ruller temaet ud, nogle indstillinger i Shopware-administrationen, ny tekst på andre sprog end engelsk og tysk og dine beslutninger om det, der forbliver MANUAL.
- Din tilladelse til en fuld scanning af din webshop, som Validiscan registrerer før scanningen. En fuld scanning lægger et produkt i kurven og åbner det første trin i kassen uden at gennemføre et køb eller indtaste betalingsoplysninger.
- Én vej ind i dit tema: adgang til det GitHub-repository, der rummer temapluginet, eller en ZIP-fil med pluginets mappe under
custom/plugins, uploadet i kundeportalen. - Dit svar på, om AI må udarbejde rettelser på niveau ASSISTED. AI-udkast er slået fra, indtil du siger ja.
- En udvikler, der gennemgår ændringerne, merger pull requesten eller anvender patchpakken, bygger temaet og ruller det ud.
- De indstillinger i Shopware-administrationen, som rettelserne ikke ændrer: metatitler til sider, der ingen har, sproget for indhold, der er skrevet på et andet sprog end din webshops, og en farve, der er gemt i temaindstillingerne, når en kontrastrettelse ændrer den farve.
- Tekst på webshoppens andre sprog end engelsk og tysk, hvor en rettelse tilføjer ny tekst.
- Dine beslutninger om det, der forbliver MANUAL, for eksempel undertekster til dine videoer.
Detaljer: når ændringerne er live, og hvad et projekt dækker
Når ændringerne er live, kontrollerer en verifikationsscanning de berørte sider igen, og Remediation Evidence Package registrerer resultatet. Sådan forløber et projekt, trin for trin
Et projekt dækker én webshop: ét domæne og ét tema. Det gælder en storefront bygget på et tema; en headless storefront fås på forespørgsel.
Kilder
2 kilder, alle kontrolleret til denne side den 6. oktober 2026.
Shopwares udviklerdokumentation 2
- Add SCSS Styling and JavaScript to a Theme · Shopware · kontrolleret
- Add custom JavaScript · Shopware · kontrolleret
Begynd med et gratis tjek af din webshop.
Send din webshops adresse. Validiscan scanner den og svarer med hver fejl, scanningen kan påvise, med siden og koden.
Bestil et gratis tjekEller skriv til info@validiscan.com.
Hvad det gratis tjek omfatter, og hvad det udelader- Du sender
- din webshops adresse
- Sider, der scannes
- op til 15
- Du får
- hver fejl, scanningen kan påvise, med siden og koden
- På din webshop
- kun offentlige sider; intet login, intet købt, ingen formularer sendt
- Hvad det ikke er
- et fuldt audit