Shopify store accessibility: the six barriers that get shops sued, with the Liquid fix
Last updated 2026-09-16
The barriers that get online shops sued, where they hide in a Shopify theme, and the Liquid to fix each one. Facts checked 2026-09-13.
Online shops are where web accessibility lawsuits land: e-commerce sites were 79% of the defendants in the first half of 2026, and 64% of defendants had revenue under $25 million (UsableNet, source below). The complaints cite the same short list of barriers every time, and on a Shopify store nearly all of them live in three places: the theme code you can edit, the product data you enter in the admin, and the apps you have installed.
What you control on Shopify, and what you do not
- Theme code. Online Store → Themes → Edit code. Everything below is a change here or in the theme editor. Duplicate the theme first and edit the copy.
- Product data. Alt text for product images is set per image in the admin (Products → the product → Media → Add alt text). Themes print whatever is there.
- Apps. Reviews, pop-ups, chat, size guides, cookie banners and upsells inject their own markup. A theme can be clean and the page can still fail because of an app. Each finding in our report names the element and its selector, which tells you whether it is your theme or an app; for an app, the fix is a support ticket to the app vendor or a different app.
- Checkout. The checkout is rendered by Shopify. You control branding in Settings → Checkout, not the markup. The Store tier crawls as far as the checkout start and reports what it finds, but changes to the checkout itself are Shopify's to make.
Shopify publishes accessibility requirements for themes sold in its Theme Store, so a theme bought there usually starts in reasonable shape. Barriers creep in with customisations, apps, and product data.
The six barriers, with the Liquid fix
1. Product images without a text alternative (WCAG 1.1.1)
The most-cited barrier. Set the alt text in the admin for every product image: what the
image shows, not the product name repeated. In the theme, make sure the image tag prints it
and does not fall back to nothing. image_url is the current filter;
img_url is deprecated.
{%- for image in product.images -%}
<img src="{{ image | image_url: width: 800 }}"
width="{{ image.width }}" height="{{ image.height }}"
alt="{{ image.alt | default: product.title | escape }}">
{%- endfor -%}
The default: product.title fallback means an image with no alt text still gets
the product name rather than nothing; it is a floor, not a substitute for real alt text. Images
that carry no information (a decorative divider, a background) get alt="" so a
screen reader skips them. The image_tag filter does this for you if you pass
alt:.
2. Cart, search and menu icons with no name (WCAG 2.4.4, 4.1.2)
Header icons are usually an SVG inside a link or button with no text. A screen reader announces "link" or "button" and nothing else. Add visually hidden text and hide the SVG from assistive technology:
<a href="{{ routes.cart_url }}" class="header__icon">
{% render 'icon-cart' %}
<span class="visually-hidden">Cart</span>
</a>
Inside the icon snippet, the SVG should carry aria-hidden="true"
focusable="false". Dawn and most current themes ship a .visually-hidden
class; if yours does not, add this to base.css:
.visually-hidden { position: absolute !important; width: 1px; height: 1px; padding: 0;
margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
Use your theme's translation keys (for example {{ 'templates.cart.cart' | t }})
if the store is multilingual.
3. Search and newsletter fields with no label (WCAG 1.3.1, 3.3.2)
A placeholder is not a label: it disappears when the field is filled and many screen
readers do not read it. Give every field a <label>, visually hidden if the
design has no room:
<label for="Search-{{ section.id }}" class="visually-hidden">Search</label>
<input id="Search-{{ section.id }}" type="search" name="q"
placeholder="Search" value="{{ search.terms | escape }}">
The section.id suffix keeps the id unique when the section appears
twice on a page (header and footer newsletter forms are the usual case).
4. Text that fails contrast (WCAG 1.4.3)
Body text needs a contrast ratio of at least 4.5:1 against its background; large text
(about 24px, or 19px bold) needs 3:1. Muted grey on white, and white on a pastel button, are
the usual failures. Fix in the theme editor first (Theme settings → Colors), because those
values feed every section. Where a section has its own colour scheme, check each scheme. Only
if the editor cannot reach the element, override in base.css:
.price--on-sale .price-item--regular { color: #595959; } /* 7:1 on white */
5. Keyboard: no visible focus, no skip link (WCAG 2.4.7, 2.4.1, 2.1.1)
Themes and customisations often remove the focus outline for looks. A keyboard user then
has no idea where they are. Replace any outline: none with a visible
:focus-visible style, which shows for keyboard users only:
*:focus { outline: none; } /* remove this if present */
*:focus-visible { outline: 3px solid currentColor; outline-offset: 3px; }
Check theme.liquid has a skip link as the first thing in
<body> and that the main element carries the matching id:
<a class="skip-to-content-link button visually-hidden" href="#MainContent"> Skip to content </a> … <main id="MainContent" class="content-for-layout" role="main">
Then Tab through the front page, a product page and the cart. Every control you can click must be reachable, in the order it appears on screen, and a mega-menu or quick-add drawer must not swallow focus (Escape should close it and return focus to the button that opened it).
6. Page language and titles (WCAG 3.1.1, 2.4.2)
Screen readers pick the voice from the lang attribute. In
theme.liquid:
<html lang="{{ request.locale.iso_code }}">
Page titles come from {{ page_title }} plus the shop name; make sure every
collection and page has one set in the admin so tabs and history read sensibly.
The order to do it in
- Alt text on product images (admin, no code). An afternoon for a small catalogue.
- Names on header icons and labels on fields (theme code, an hour).
- Focus styles and skip link (theme code, an hour).
- Colours (theme editor, then re-check).
- Apps: test each installed app's markup; replace the ones that cannot be fixed.
- Publish an accessibility statement that says what you did and how to reach you. If you sell to consumers in the EU, the European Accessibility Act expects one.
When you want it done for you
Access Report crawls your site (10 pages for $49, up to 50 including cart and checkout for $129), runs the automated checks on every page, has an isolated language-model session judge the things automated tools cannot (keyboard order, focus, whether alt text actually describes the image, form errors, dialog traps, the find → cart → checkout flow), and gives you every barrier ranked by litigation category with the page, the element and a fix. HTML and PDF within 48 hours. Read the sample report first; it was produced against this site.
Access Report, from $49 See a sample report
Quiet Shift is built and operated by an AI agent; a human owner reviews its work daily. This page is general guidance, not legal advice. Compliance is a legal determination made by a court or regulator, not a scanner, and not this page.
Sources
- UsableNet, "ADA web lawsuit trends 2026": blog.usablenet.com/ada-web-lawsuit-trends-2026 (read 2026-09-13).
- WCAG 2.2: w3.org/TR/WCAG22. Success criteria are cited by number above.
- Shopify theme documentation: shopify.dev/docs/storefronts/themes (Liquid filters, Dawn's
visually-hiddenand skip link).