EN 301 549 · EAA · WCAG 2.1
Web accessibility report
Clear results. Next steps you can act on.
Automated analysis of accessibility barriers on the shop’s public page.
Accy · Accessibility compliance for European online shops.
Scanned on 15 September 2026 at 20:55
tienda-de-ejemplo.es
Critical risk
- 22 rules failed
- 9 rules passed
- 5 to review by hand
29 findings in total, split like this
- 6 Critical
- 15 Serious
- 7 Moderate
- 1 Minor
- Platform detected
- Shopify · Dawn
- No accessibility statement found
- Generate one, free →
- Technical scope
- One public page, analysed from the HTML and CSS the server delivers.
Suggested reading order
Start with the 21 critical and serious findings in section 02: those are the ones that stop a purchase. Then check by hand the 5 points no tool can confirm, walking the product page, basket and checkout with a keyboard and a screen reader. And scan again when you are done: this report is dated and works as a regression check.
| Finding | Risk | Reference |
|---|---|---|
| Links with no nameSome links have no visible text and no accessible name. | Critical | WCAG 2.4.4, 4.1.2 (A) · EN 301 549 9.2.4.4, 9.4.1.2 |
| Form fields with no labelSome form fields have no accessible name: no <label>, no aria-label, no aria-labelledby. | Critical | WCAG 1.3.1, 3.3.2, 4.1.2 (A) · EN 301 549 9.1.3.1, 9.3.3.2, 9.4.1.2 |
| Buttons with no nameSome buttons have no visible text and no accessible name. | Critical | WCAG 4.1.2 (A) · EN 301 549 9.4.1.2 |
| Insufficient colour contrastThere is 18px text with a contrast ratio of 2.35:1 against its background, where the standard requires 4.5:1. | Serious | WCAG 1.4.3 (AA) · EN 301 549 9.1.4.3 |
| No accessibility statement foundWe found no link to an accessibility statement on this page. | Serious | EN 301 549 Annex V |
| Alternative text that carries no informationSome images have alt text that is a file name, a code, or a generic word like "image" or "photo". | Serious | WCAG 1.1.1 (A) · EN 301 549 9.1.1.1 |
| Embedded frame with no titleThere is an <iframe> with no title attribute. | Serious | WCAG 4.1.2, 2.4.1 (A) · EN 301 549 9.4.1.2 |
| The placeholder is doing the label’s jobSome fields get their only accessible name from the placeholder attribute. | Serious | WCAG 3.3.2 (A) · EN 301 549 9.3.3.2 |
| Data table with no header cellsThere is a table with data but no <th> cells. | Serious | WCAG 1.3.1 (A) · EN 301 549 9.1.3.1 |
| The focus indicator is switched offCSS removes the focus outline (a:focus) without putting anything visible in its place. | Serious | WCAG 2.4.7 (AA) · EN 301 549 9.2.4.7 |
| Clickable element unreachable by keyboardThere is a <div> with a click handler but no role and no place in the tab order. | Serious | WCAG 2.1.1, 4.1.2 (A) · EN 301 549 9.2.1.1 |
| Video with no captionsThere is a <video> with no captions track. | Serious | WCAG 1.2.2 (A) · EN 301 549 9.1.2.2 |
| Sound that plays by itselfThere is a <video> with autoplay and no mute. | Serious | WCAG 1.4.2 (A) · EN 301 549 9.1.4.2 |
| Missing document languageThe <html> element declares no valid language. | Serious | WCAG 3.1.1 (A) · EN 301 549 9.3.1.1 |
| The page blocks zoomingThe viewport tag blocks zoom (width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no). | Serious | WCAG 1.4.4 (AA) · EN 301 549 9.1.4.4 |
| Links with generic textSome links read "read more", "click here", "learn more" or similar. | Moderate | WCAG 2.4.4 (A) · EN 301 549 9.2.4.4 |
| Heading levels skippedThe page jumps from one heading level to another, skipping the ones in between (h1 to h4). | Moderate | WCAG 1.3.1 (A) · EN 301 549 9.1.3.1 |
| Non-existent ARIA roleAn element has role="buton", which is not a valid role. | Moderate | WCAG 4.1.2 (A) · EN 301 549 9.4.1.2 |
| Non-existent ARIA attributeAn element has the attribute aria-labl, which is not part of the specification. | Moderate | WCAG 4.1.2 (A) · EN 301 549 9.4.1.2 |
| Positive tabindex valueSome elements use tabindex="4". | Moderate | WCAG 2.4.3 (A) · EN 301 549 9.2.4.3 |
| Missing main content regionThe page has no <main>, or has more than one. | Moderate | WCAG 1.3.1 (A) · EN 301 549 9.1.3.1 |
| Duplicate idsThe id "col" appears 3 times. | Minor | WCAG 4.1.1 (A) · EN 301 549 9.4.1.1 |
Now · 0–7 days
Clear the blockers
Publish the accessibility statement and fix everything marked critical or serious. That is what stops a purchase and what is visible from outside.
Next cycle
Fix it in the theme
Moderate and minor findings usually come from the theme or a repeated component. Fixing them there stops each new product bringing them back.
Validation
Test the purchase by hand
Walk the product page, basket and checkout with a keyboard and a screen reader. No automated tool covers that part, and it is where the sale is lost.
What to fix
Links with no name
Critical4 times on this page · WCAG 2.4.4, 4.1.2 (A) · EN 301 549 9.2.4.4, 9.4.1.2
Some links have no visible text and no accessible name.
Why it matters
Screen readers let you list every link on a page to navigate quickly. An unnamed link shows up in that list as the raw URL, or just as "link". It usually hits social icons in the footer and product cards where only the image is linked.
How to fix it
Give it visible text, or if it is an icon, an aria-label naming the destination.
As it is <a href="https://instagram.com/shop"><svg>…</svg></a>As it should be <a href="https://instagram.com/shop" aria-label="Follow us on Instagram"> <svg aria-hidden="true">…</svg> </a>See where it happens
body.template-index > div.header:nth-of-type(1) > aThe image inside has no alt attribute.
<a href="/"><img src="/cdn/shop/files/logo_final_v2.png"></a>body.template-index > div.grid:nth-of-type(3) > div.card:nth-of-type(1) > a:nth-of-type(1)The image inside has no alt attribute.
<a href="/products/camiseta-arena"><img src="/cdn/shop/products/DSC_0042.jpg"></a>body.template-index > div.footer:nth-of-type(6) > div.social:nth-of-type(4) > a:nth-of-type(1)There is only an icon, with no title or label.
<a href="https://instagram.com/tienda"><svg viewBox="0 0 24 24"><circle cx="12" cy="12" r="9" /></svg></a>body.template-index > div.footer:nth-of-type(6) > div.social:nth-of-type(4) > a:nth-of-type(2)There is only an icon, with no title or label.
<a href="https://facebook.com/tienda"><svg viewBox="0 0 24 24"><rect width="18" height="18" x="3" y="3" /></svg></a>
Form fields with no label
Critical1 time on this page · WCAG 1.3.1, 3.3.2, 4.1.2 (A) · EN 301 549 9.1.3.1, 9.3.3.2, 9.4.1.2
Some form fields have no accessible name: no <label>, no aria-label, no aria-labelledby.
Why it matters
An unlabelled field is announced as "edit text" and nothing more. In a search box that is annoying; in the shipping address at checkout it makes the purchase impossible to complete without guessing.
A confusing field at checkout is an abandoned basket. This is not only compliance, it is conversion.
How to fix it
Associate a <label> using the for attribute pointing at the field id, or wrap the field inside the label. A placeholder does not count: it disappears as soon as someone types, and many screen readers never announce it.
On your platform · Shopify
Shopify's own checkout fields are already labelled. Check the ones you added: footer newsletter, header search, and any third-party app forms.
As it is <input type="email" name="email">As it should be <label for="email">Email address</label> <input type="email" id="email" name="email" autocomplete="email"> <!-- Or by wrapping --> <label>Postcode <input type="text" name="postcode" autocomplete="postal-code"> </label>See where it happens
body.template-index > div.newsletter:nth-of-type(5) > form > input:nth-of-type(1)<input type="email" name="email">
Buttons with no name
Critical1 time on this page · WCAG 4.1.2 (A) · EN 301 549 9.4.1.2
Some buttons have no visible text and no accessible name.
Why it matters
This usually hits icon-only buttons: the close X, the search magnifier, the basket in the header. A screen reader announces them as "button" and the person has to activate them to find out what they do.
How to fix it
If the button has visible text, you are done. If it is icon-only, add an aria-label with the action and mark the icon aria-hidden="true".
On your platform · Shopify
In Dawn and its derivatives, header icon buttons live in sections/header.liquid.
As it is <button><svg>…</svg></button>As it should be <button aria-label="Dismiss notice"> <svg aria-hidden="true">…</svg> </button>See where it happens
body.template-index > div.header:nth-of-type(1) > button.cart-toggleThere is only an icon, with no title or label.
<button class="cart-toggle"><svg viewBox="0 0 24 24"><path d="M7 4h14l-2 9H8z" /></svg></button>
Insufficient colour contrast
Serious4 times on this page · WCAG 1.4.3 (AA) · EN 301 549 9.1.4.3
There is 18px text with a contrast ratio of 2.35:1 against its background, where the standard requires 4.5:1.
Why it matters
This is the most widespread barrier and the one that affects the most people: anyone with tired eyes, a phone in bright sunlight, or a cheap screen. You do not need a diagnosed disability to be unable to read light grey on white.
The text that usually fails is exactly the text that sells: struck-through prices, delivery costs, stock messages.
How to fix it
Darken the text or lighten the background until it meets the required ratio. Normal text needs 4.5:1; from 24px (or 18.66px bold) 3:1 is enough. Greys around #999 on white almost never pass.
On your platform · Shopify
In the theme editor, Settings › Colors lets you change the theme colour schemes without touching code.
As it is /* 2.85:1 — fails */ .old-price { color: #999999; background: #ffffff; }As it should be /* 4.83:1 — passes */ .old-price { color: #717171; background: #ffffff; }See where it happens
body.template-index > div.hero:nth-of-type(2) > p.hero-sub<p class="hero-sub">Fabricada en España con algodón orgánico certificado.</p>body.template-index > div.grid:nth-of-type(3) > div.card:nth-of-type(1) > span.price-old:nth-of-type(1)<span class="price-old">29,00 €</span>body.template-index > div.grid:nth-of-type(3) > div.card:nth-of-type(1) > a:nth-of-type(2)<a href="/products/camiseta-arena">Leer más</a>body.template-index > div.footer:nth-of-type(6) > p.legal<p class="legal">© 2026 Tienda de ejemplo. Todos los derechos reservados.</p>
No accessibility statement found
Serious1 time on this page · EN 301 549 Annex V
We found no link to an accessibility statement on this page.
Why it matters
The European Accessibility Act requires service providers to publish information about how the service meets accessibility requirements. It is the one thing a market surveillance authority can check without opening a single developer tool: they look at your footer, and if it is not there, they have a documented failure.
This is the cheapest failure on the list to fix and the easiest to spot from outside. Fixing it is an afternoon; being caught is a case file.
How to fix it
Publish an accessibility page and link it from the footer, next to your legal notice and privacy policy. State the conformance level you claim, the parts you know do not yet conform, the date of the last review, and a way to report barriers.
On your platform · Shopify
Create the page under Online Store › Pages, then add it to your footer menu under Navigation.
As it is <footer> <a href="/legal">Legal notice</a> <a href="/privacy">Privacy</a> </footer>As it should be <footer> <a href="/legal">Legal notice</a> <a href="/privacy">Privacy</a> <a href="/accessibility">Accessibility statement</a> </footer>Alternative text that carries no information
Serious1 time on this page · WCAG 1.1.1 (A) · EN 301 549 9.1.1.1
Some images have alt text that is a file name, a code, or a generic word like "image" or "photo".
Why it matters
An alt that reads "DSC_0042.jpg" or "product" satisfies the form but not the function: the person still has no idea what is in the picture. It usually happens when a catalogue was bulk-imported and the field was filled automatically.
How to fix it
Describe the actual content. For products the formula that works is: what it is + distinguishing feature + variant. "Organic cotton t-shirt in sand" works; "product" does not.
On your platform · Shopify
If you imported your catalogue from a CSV, check the "Image Alt Text" column and re-import with real descriptions instead of file names.
As it is <img src="/p1.jpg" alt="image"> <img src="/p2.jpg" alt="DSC_0042.jpg">As it should be <img src="/p1.jpg" alt="Grey running shoe with orange sole"> <img src="/p2.jpg" alt="Black canvas 20-litre backpack, side view">See where it happens
body.template-index > div.grid:nth-of-type(3) > div.card:nth-of-type(2) > a:nth-of-type(1) > img<img src="/cdn/shop/products/sudadera.jpg" alt="imagen">
Embedded frame with no title
Serious1 time on this page · WCAG 4.1.2, 2.4.1 (A) · EN 301 549 9.4.1.2
There is an <iframe> with no title attribute.
Why it matters
Screen readers can list the frames on a page. With no title they show up as "frame", "frame", "frame", and the person has to enter each one to find out which is the video, which the map and which the chat widget.
Thirty seconds per frame to fix, and it appears in every audit report.
How to fix it
Add a title describing what the frame contains. If the iframe is an invisible tracking pixel, mark it aria-hidden="true" as well as hiding it.
On your platform · Shopify
If the video comes from a theme block, edit the template under Online Store › Themes › Edit code and add the title to the iframe.
As it is <iframe src="https://www.youtube.com/embed/xyz"></iframe>As it should be <iframe src="https://www.youtube.com/embed/xyz" title="Video: how to choose your size"></iframe>See where it happens
body.template-index > iframe<iframe src="https://www.youtube.com/embed/dQw4w9WgXcQ" width="560" height="315"></iframe>
The placeholder is doing the label’s job
Serious1 time on this page · WCAG 3.3.2 (A) · EN 301 549 9.3.3.2
Some fields get their only accessible name from the placeholder attribute.
Why it matters
Placeholder text vanishes the moment someone starts typing. Anyone who gets distracted halfway through a form can no longer tell what belonged in that field, and anyone with memory or attention difficulties is left with no reference at all. Its contrast is usually very low by design, too.
How to fix it
Add a visible <label>. You can keep the placeholder as a format hint ("e.g. SW1A 1AA"), but never as a substitute for the field name.
As it is <input type="text" name="postcode" placeholder="Postcode">As it should be <label for="postcode">Postcode</label> <input type="text" id="postcode" name="postcode" placeholder="e.g. SW1A 1AA" autocomplete="postal-code">See where it happens
body.template-index > div.header:nth-of-type(1) > form.search > input<input type="text" name="q" placeholder="Buscar productos">
Data table with no header cells
Serious1 time on this page · WCAG 1.3.1 (A) · EN 301 549 9.1.3.1
There is a table with data but no <th> cells.
Why it matters
In a properly marked-up table, a screen reader announces "Size: M, Price: £19" as the person moves between cells. Without headers it reads only "M, £19", and they have to remember the column order.
How to fix it
Turn the first row (or column) into <th> and add scope="col" or scope="row".
On your platform · Shopify
Size guide tables are usually written in the rich text editor of the product description; edit the HTML with the "</>" button.
As it is <tr><td>Size</td><td>Price</td></tr> <tr><td>M</td><td>£19</td></tr>As it should be <tr><th scope="col">Size</th><th scope="col">Price</th></tr> <tr><td>M</td><td>£19</td></tr>See where it happens
body.template-index > div.sizes:nth-of-type(4) > table<table> <tr><td>Talla</td><td>Pecho</td><td>Largo</td></tr> <tr><td>S</td><td>96 cm</td><td>68 cm</td></tr> <tr><td>M</td><td>101 cm</td><td>70 cm</td></tr> </table>
The focus indicator is switched off
Serious1 time on this page · WCAG 2.4.7 (AA) · EN 301 549 9.2.4.7
CSS removes the focus outline (a:focus) without putting anything visible in its place.
Why it matters
Anyone navigating with Tab needs to see where they are. With no focus indicator the person presses Tab and cannot tell which element is selected: navigating turns into guessing. It is one of the most disabling failures and one of the easiest to fix.
A single `outline: none` in a theme stylesheet can make the whole shop unusable by keyboard.
How to fix it
Never use outline: none without a replacement. If the default ring clashes with your design, draw your own, with at least 3:1 contrast against the background.
As it is a:focus, button:focus { outline: none; }As it should be a:focus-visible, button:focus-visible { outline: 3px solid #005fcc; outline-offset: 2px; }See where it happens
a:focusa:focus { outline: none }
Clickable element unreachable by keyboard
Serious1 time on this page · WCAG 2.1.1, 4.1.2 (A) · EN 301 549 9.2.1.1
There is a <div> with a click handler but no role and no place in the tab order.
Why it matters
A mouse can click anything; a keyboard cannot. A <div> with onclick is invisible to anyone navigating with Tab, with a switch, or by voice control. If that div is "Add to basket", the shop is unusable.
This is the failure that most often leaves a checkout completely blocked.
How to fix it
Use <button>. It handles focus, activation with Enter and Space, and role announcement, all at once and with no extra JavaScript.
As it is <div onclick="addToCart()">Add to basket</div>As it should be <button type="button" onclick="addToCart()">Add to basket</button>See where it happens
body.template-index > div.hero:nth-of-type(2) > div.cta<div class="cta" onclick="location.href='/collections/novedades'">Ver la colección</div>
Video with no captions
Serious1 time on this page · WCAG 1.2.2 (A) · EN 301 549 9.1.2.2
There is a <video> with no captions track.
Why it matters
Without captions the video does not exist for anyone who cannot hear. Nor for the majority of people browsing on a phone with the sound off, which is nearly everyone.
How to fix it
Add a <track kind="captions"> with a WebVTT file. If the video is hosted on YouTube or Vimeo, turn captions on there and proofread them: the automatic ones are usually wrong.
As it is <video src="/promo.mp4" controls></video>As it should be <video src="/promo.mp4" controls> <track kind="captions" src="/promo-en.vtt" srclang="en" label="English" default> </video>See where it happens
body.template-index > div.hero:nth-of-type(2) > video<video src="/cdn/shop/videos/hero.mp4" autoplay loop></video>
Sound that plays by itself
Serious1 time on this page · WCAG 1.4.2 (A) · EN 301 549 9.1.4.2
There is a <video> with autoplay and no mute.
Why it matters
Unexpected audio talks over the screen reader and makes the page unreadable until it can be stopped. Finding the pause button without seeing the screen, while it is playing, is exactly as hard as it sounds.
How to fix it
Remove autoplay, or add muted. If you need automatic playback, keep it under three seconds or give it a stop control at the top of the page.
As it is <video src="/hero.mp4" autoplay loop></video>As it should be <video src="/hero.mp4" autoplay loop muted playsinline></video>See where it happens
body.template-index > div.hero:nth-of-type(2) > video<video src="/cdn/shop/videos/hero.mp4" autoplay loop></video>
Missing document language
Serious1 time on this page · WCAG 3.1.1 (A) · EN 301 549 9.3.1.1
The <html> element declares no valid language.
Why it matters
Screen readers pick the voice and pronunciation from that attribute. Without it, a Spanish shop can be read with English phonetics, and nothing is intelligible.
A thirty-second fix affecting every page on the site. Start here.
How to fix it
Add lang="en" (or your language) to the <html> element. One attribute, one line, and it fixes the whole page.
On your platform · Shopify
In layout/theme.liquid, the first line should be <html lang="{{ request.locale.iso_code }}">.
As it is <html>As it should be <html lang="en">The page blocks zooming
Serious1 time on this page · WCAG 1.4.4 (AA) · EN 301 549 9.1.4.4
The viewport tag blocks zoom (width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no).
Why it matters
Plenty of people zoom in on their phone to read. Blocking it for design reasons simply cuts them off from the content. The standard requires zooming to at least 200%.
How to fix it
Remove user-scalable=no and any maximum-scale below 2.
As it is <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">As it should be <meta name="viewport" content="width=device-width, initial-scale=1">See where it happens
head > meta:nth-of-type(2)<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
Links with generic text
Moderate2 times on this page · WCAG 2.4.4 (A) · EN 301 549 9.2.4.4
Some links read "read more", "click here", "learn more" or similar.
Why it matters
Out of context that text says nothing. In the link list a screen reader generates, a category page turns into twenty identical entries all saying "read more".
Link text is one of the signals Google uses to understand the destination page. "Read more" tells it nothing either.
How to fix it
Put the destination in the link itself: "See the organic cotton t-shirt". If the design demands keeping "Read more" visible, add a full aria-label.
As it is <h3>Sand t-shirt</h3> <a href="/p/1">Read more</a>As it should be <h3>Sand t-shirt</h3> <a href="/p/1" aria-label="See the sand t-shirt">Read more</a> <!-- Better still --> <a href="/p/1">See the sand t-shirt</a>See where it happens
body.template-index > div.grid:nth-of-type(3) > div.card:nth-of-type(1) > a:nth-of-type(2)<a href="/products/camiseta-arena">Leer más</a>body.template-index > div.grid:nth-of-type(3) > div.card:nth-of-type(2) > a:nth-of-type(2)<a href="/products/sudadera-gris">Leer más</a>
Heading levels skipped
Moderate1 time on this page · WCAG 1.3.1 (A) · EN 301 549 9.1.3.1
The page jumps from one heading level to another, skipping the ones in between (h1 to h4).
Why it matters
Headings are the table of contents people navigate a page by. When levels skip, that outline stops reflecting the real hierarchy and the person cannot tell whether the new section belongs to the previous one or starts fresh.
How to fix it
Use levels in order. If you skipped a level because of font size, set the correct level and adjust the size in CSS.
As it is <h1>Shop</h1> <h4>Offers</h4>As it should be <h1>Shop</h1> <h2 class="small-heading">Offers</h2>See where it happens
body.template-index > h4<h4>Más vendidos</h4>
Non-existent ARIA role
Moderate1 time on this page · WCAG 4.1.2 (A) · EN 301 549 9.4.1.2
An element has role="buton", which is not a valid role.
Why it matters
A misspelled role does nothing: the browser ignores it and the element is exposed with its original semantics, which is almost always "no meaning at all". The developer believes it is fixed, and it is not.
How to fix it
Correct the role name, or drop it and use the native HTML element, which already carries the right role.
As it is <span role="buton">Buy</span>As it should be <button type="button">Buy</button>See where it happens
body.template-index > span<span role="buton" aria-labl="ayuda" tabindex="4">Ayuda</span>
Non-existent ARIA attribute
Moderate1 time on this page · WCAG 4.1.2 (A) · EN 301 549 9.4.1.2
An element has the attribute aria-labl, which is not part of the specification.
Why it matters
Same as an invented role: the browser discards it silently. These are usually typos (aria-labl, aria-describe) that leave the element without the name or description it was meant to have.
How to fix it
Check the attribute spelling against the WAI-ARIA specification.
See where it happens
body.template-index > span<span role="buton" aria-labl="ayuda" tabindex="4">Ayuda</span>
Positive tabindex value
Moderate1 time on this page · WCAG 2.4.3 (A) · EN 301 549 9.2.4.3
Some elements use tabindex="4".
Why it matters
A positive tabindex pulls the element out of its natural place in the tab order and puts it ahead of everything else. Focus then jumps around the page in an order that does not match what is on screen, and it becomes unmaintainable as the page grows.
How to fix it
Use tabindex="0" to make an element focusable, or tabindex="-1" to focus it programmatically. If the order is wrong, change the order of the HTML.
See where it happens
body.template-index > span<span role="buton" aria-labl="ayuda" tabindex="4">Ayuda</span>
Missing main content region
Moderate1 time on this page · WCAG 1.3.1 (A) · EN 301 549 9.1.3.1
The page has no <main>, or has more than one.
Why it matters
The "skip to main content" shortcut is the fastest way past the navigation, which repeats identically on every page. Without <main> that shortcut does not exist and the whole menu has to be tabbed through each time.
How to fix it
Wrap the page’s own content (not the header, navigation or footer) in a single <main>.
Duplicate ids
Minor1 time on this page · WCAG 4.1.1 (A) · EN 301 549 9.4.1.1
The id "col" appears 3 times.
Why it matters
Accessibility references (label for, aria-labelledby, aria-describedby) point at an id and always resolve to the first match. With duplicate ids, one field’s label can end up describing another.
How to fix it
Make every id unique. If it comes from a repeated component, append the index or the product id.
See where it happens
#col<div id="col"><a href="/pages/privacidad">Política de privacidad</a></div>
To review by hand
ARIA reference to an id that does not exist
The attribute aria-labelledby points at the ids titulo-inexistente, which are not on the page.
Check the id exists and matches exactly, case included. If the target is gone, replace the reference with an aria-label.
Personal data fields with no autocomplete
Some fields asking for common personal data (email, phone, address) have no autocomplete attribute.
Add the matching standard token: autocomplete="email" in this case.
Required field marked visually only
The field label says it is required (with an asterisk or the word), but the field itself declares neither required nor aria-required.
Add the required attribute to the field. Keep the visual marker too: both, not one or the other.
Missing landmark regions
The page does not mark up some of its main regions: navigation, banner, contentinfo.
Use the correct semantic elements: <header>, <nav>, <main> and <footer>, instead of <div class="header">.
Extremely small text
There is text below 10px (9px).
Go up to at least 12px, and 16px in the main content. Use relative units (rem) so it respects browser settings.
What is already fine
- Images with no alternative text
- Redundant alternative text
- Meaningful SVG icon with no name
- Links that display the full URL
- Missing main heading, or more than one
- The page has no headings
- Empty headings
- Element with an interactive role but no name
- Missing or empty page title
How far this report goes
We scanned a single page, using the HTML and CSS the server returns. We do not execute JavaScript, so anything generated after load (dropdown menus, modals, checkout steps) is out of scope. And no automated tool covers more than 30-40% of WCAG criteria: the rest requires a person testing the shop with a keyboard and a screen reader.
References
- EN 301 549 V3.2.1 — Accessibility requirements for ICT products and services
- W3C — Web Content Accessibility Guidelines (WCAG) 2.1
- Directiva (UE) 2019/882 — European Accessibility Act
This report is not legal advice.
Want this in writing?
We will send you this report as a PDF, the order worth fixing it in, and a note if the law changes in a way that affects you. Written by a person, not an automated newsletter, and your address goes nowhere else.
Keep it from breaking again
Every theme change, every new app and every imported product can reintroduce these barriers. Monitoring scans your whole shop weekly, alerts you when something gets worse, and keeps the dated history — which is exactly what you show if anyone asks.
See plans