Developer reviewing Shopify theme code on a laptop while checking storefront accessibility

How to Fix Shopify Accessibility Bugs That Block WCAG AA

How to Fix Shopify Accessibility Bugs That Block WCAG AA

Aug 23, 2026

Octavian Contis 12 minutes

Share

Merchants keep asking whether a Shopify store can reach WCAG AA, usually after a scanner report, a demand letter, or a buyer who cannot finish the purchase path on a keyboard. Most storefronts can get close when you fix the HTML you own. Hosted checkout and new customer accounts stay on Shopify's side of the line.

The ten bugs below are the ones that show up again and again on theme audits: empty alt text, weak contrast, missing labels, vanished focus rings, hover-only menus, colour-only swatches, broken skip links, unnamed icon buttons, drawer focus traps, and silent cart or price updates.

Overlay widgets leave that source HTML unchanged. Theme Liquid, product content, and a ruthless app audit are what move a store toward WCAG AA.

Introduction

Shopify accessibility work fails when teams treat it as a plugin install. The community pattern is consistent: someone asks whether WCAG AA is even possible, someone else recommends an overlay after an ADA letter, and a third thread reports checkout or customer-account errors the merchant cannot edit.

This reflects patterns we see regularly across the Shopify merchant and developer community.

The useful split is ownership. You control theme templates, section settings, product media, and most Online Store 2.0 markup. Apps inject popups, reviews, chat, and filters that ignore keyboard and screen-reader contracts. Shopify hosts checkout and the new customer sign-in, and those surfaces can fail contrast or label checks you will never reach in theme.liquid.

This article is a fix path for the ten ecommerce accessibility bugs that actually block Shopify stores, plus a diagnose-before-you-remediate sequence so you stop paying for overlays that scanners still fail. For the conversion cost of inaccessible themes, see Common Theme Mistakes That Kill Conversion Rates. For how Liquid decides what the browser announces, see Liquid Explained for Store Owners.

What merchants are running into

The first question is usually binary in the merchant's head: is Shopify accessible, or is the whole platform a liability. The operational question is narrower. Which failures sit in your theme and catalogue, which sit in apps, and which sit in Shopify-hosted HTML.

Merchants who try to "bring the shop up to WCAG AA" typically hit the same wall. Theme contrast and labels can be fixed in days. Then an audit flags hosted checkout contrast, missing icon roles, or the new customer account page, and there is no Liquid file to edit. Shopify publishes a checkout accessibility conformance report and still lists partial support on contrast and focus. That is a platform ticket, not a theme sprint.

A second cluster arrives as legal panic. Stores install AccessiBe-class widgets after a demand letter, then discover Lighthouse barely moves and screen readers still announce empty buttons. Overlays can offer user preferences. They do not write alt on product media or give a hamburger button an accessible name.

A third cluster is app sprawl. Reviews, chat, upsell popups, and mega-menu apps inject the worst markup on the page: unlabelled close buttons, focus traps, and star ratings announced as "graphic graphic graphic". That pattern sits beside the subscription pile we mapped in The Hidden Cost of Running a Shopify Store When 12 Apps Quietly Eat Your Margins.

Why this happens

Shopify ships no WCAG toggle. Theme Store review covers performance and code quality rather than accessibility certification. Dawn is a better baseline than most premiums, and a brand palette plus two app embeds will still recreate AA failures.

Themes also optimise for the visual editor. outline: none on buttons looks clean in a desktop mock. Colour swatches built as clickable divs look premium in a demo. Sticky headers look modern until they cover the focused link, which is a WCAG 2.2 failure (2.4.11 Focus Not Obscured).

Content defaults make it worse. If a merchant never fills product image alt text, Liquid outputs an empty alt or a filename. Shopify will fall back to the product title in some contexts, which produces twenty identical announcements of "Navy Hoodie" on one product page.

Shopify accessibility ownership map

1 · Keyboard pass plusscan2 · Who owns the HTML?3 · Theme and catalogue4 · App embeds andpopups5 · Checkout and customeraccountsShopify accessibility ownership map
Shopify accessibility ownership map

How to diagnose it

Run this sequence before you buy an app or rewrite the theme.

Start with a keyboard pass from the skip link through header, search, a collection filter, a product with variants, add to cart, the cart drawer, and customer login. Note every control that has no visible focus, every menu that opens only on hover, and every drawer you cannot close with Escape.

Follow that with a screen-reader sample on one homepage, one product, and the cart, listening for unnamed buttons, duplicate headings, and whether variant or price changes are announced. Then run axe DevTools or Lighthouse on those same URLs and treat the score as a defect list rather than a WCAG percentage.

Tag each defect as theme, content, app, or Shopify-hosted. Theme and catalogue issues belong in a merchant sprint, app defects need removal or a vendor ticket, and hosted defects need a Shopify report plus an accessibility statement that documents the gap. Finish by disabling app embeds one at a time on a duplicate theme, because many supposed theme traps disappear when the reviews or chat widget unloads.

If checkout abandonment already looks healthy in analytics while buyers stall, pair this pass with How to Fix Shopify Checkout Abandonment When Your Funnel Looks Healthy. Accessibility failures are one reason a clean funnel still drops people who never appear as a rage-click.

How to fix it

Fix at the source. Each bug below lists the owner, the failure, and the first remediations that hold up in audits.

1. Missing or generic product image alt text

Owner: catalogue first, theme fallback second.

Shopify themes render alt="". Empty media fields become empty attributes, which scanners flag on every product page. Filenames and repeated product titles are only slightly better.

Write alt that describes the visible product: material, colour, viewpoint. Use alt="" only for decorative images. Add a Liquid fallback such as image.alt | default: product.title | escape so a blank field never ships empty. Then fix the catalogue for hero products, because a title fallback still fails when five images share one name.

2. Insufficient colour contrast

Owner: theme settings and brand palette.

Sale prices, compare-at text, footer links, and placeholder search copy are the usual 1.4.3 failures. Brand accents chosen in isolation often fail 4.5:1 on white. Large text can pass at 3:1. Component borders and focus rings need 3:1 against adjacent colours (1.4.11).

Check every pair in the theme editor, not only the primary button. Hero text on product photography fails whenever the image is pale. Do not rely on an overlay to "boost contrast" for users who never open the widget.

3. Missing form labels

Owner: theme forms, then apps.

Newsletter blocks, cart-attribute line-item properties, and review widgets often use placeholder-only fields. Placeholders disappear on input and fail as the accessible name. Associate a visible <label> with each control, or a persistent aria-label when the design hides the label.

Checkout fields on hosted checkout are Shopify's. Cart attributes you add in Liquid are yours. Plus merchants who inject custom properties through scripts create the unlabelled inputs we see most often on cart audits.

4. Hidden or missing focus indicators

Owner: theme CSS.

outline: none without a replacement fails 2.4.7. Custom buttons, drawer triggers, and swatch radios are the usual casualties. Restore a focus ring with at least 3:1 contrast, and test it on both light and dark sections.

Sticky announcement bars and sticky headers must not cover the focused control (2.4.11). If the bar sits position: sticky, give focused links enough offset, or collapse the bar when keyboard focus moves underneath it.

5. Keyboard-inaccessible menus

Owner: theme header, or the mega-menu app you installed.

Hover-only dropdowns lock out keyboard and many touch users. The menu trigger needs a real button, aria-expanded, and open/close on Enter or Space. Arrow keys inside the submenu are a usability win. Escape should close the menu and return focus to the trigger.

If you rebuilt a mega-menu in custom Liquid, you also inherited heading order, duplicate IDs, and skip-link targets. Duplicate header sections in the editor are an architecture smell, the same class of OS 2.0 drift we cover in Online Store 2.0: What Changed and Why It Matters.

6. Inaccessible variant swatches

Owner: theme product form.

Colour-only swatches fail two ways. Screen readers hear "button" with no name, and sold-out state is a grey wash with no text. Use radio inputs or buttons with an accessible name that includes colour and availability. Selected state needs more than a border colour change.

Custom metafield or metaobject swatches make this worse when the theme only knows Shopify's native colour option. If the picker shows a text label and no swatch, the accessibility fix and the merchandising fix are the same job: the theme must read your data model and still output a named, keyboard-operable control.

7. Missing or broken skip navigation

Owner: theme layout.

A skip link should be the first focusable element and must become visible on focus. The target, usually #MainContent or #main-content, must exist, and activating the link must move keyboard focus, not only scroll the page. Put tabindex="-1" on the main landmark so programmatic focus lands there.

Many Shopify themes omit the link, hide it forever, or point at an ID the layout never renders after a section-group refactor.

8. Icon-only buttons without accessible names

Owner: theme header and search, plus apps.

Cart, search, account, and hamburger controls are often SVGs inside a <button> or <a> with no text. Screen readers announce "button". Add a visually hidden label or aria-label, and hide the SVG with aria-hidden="true". The mobile menu button also needs aria-expanded.

App chat bubbles repeat this failure in the corner of every page. If the vendor will not ship a name, the widget does not belong on a storefront you are trying to take to AA.

9. Drawers, modals, and popups that trap or lose focus

Owner: theme cart drawer and quick view, then apps.

When a cart drawer or quick-view modal opens, focus should move inside it. Tab should cycle through the drawer controls, not the page behind. Escape and the close button should return focus to the trigger. Newsletter popups that appear after ten seconds without moving focus strand keyboard users on the page underneath.

Reviews lightboxes and chat windows are the frequent app offenders. Test them on a duplicate theme with embeds off, then on. If the trap only appears with the app, the fix is vendor pressure or removal, not more theme CSS.

10. Dynamic updates that stay silent

Owner: theme JavaScript on product and cart.

Variant changes update price and availability in the DOM while screen readers stay on the old announcement. Add-to-cart success appears as a drawer animation with no live region. Wrap price and availability in an aria-live="polite" region. Announce cart additions with a short status message.

Sold-out variants should stay focusable and include the sold-out state in the accessible name. A disabled add-to-cart button with no text equivalent is a dead end for keyboard buyers, which is also a conversion bug.

BugOwnerFirst fixEffort
Empty or generic image altCatalogue + theme fallbackFill media alt; Liquid defaultLow
Weak colour contrastTheme settingsRetune sale, footer, and placeholder pairsLow
Placeholder-only form labelsTheme + appsVisible label on every inputLow to medium
Missing focus ringTheme CSSReplace outline: none; check sticky headersLow
Hover-only menusTheme or mega-menu appButton trigger, aria-expanded, EscapeMedium
Unnamed colour swatchesProduct formNamed radios or buttons, including sold-outMedium
Broken skip linkLayoutVisible on focus; real main targetLow
Icon buttons with no nameHeader + appsaria-label on cart, search, menuLow
Drawer and popup focus trapsTheme + appsMove focus in, return on closeMedium
Silent price and cart updatesTheme JavaScriptLive regions on price, stock, and ATCMedium

Low-effort rows are content and CSS. Medium rows are component behaviour. None of them are solved by a storefront overlay.

When to get help

Stay in-house when the list is alt text, contrast tokens, skip links, and icon labels. Those are catalogue and CSS jobs, and they should be on every theme launch checklist.

Bring in engineering when the failures sit in a custom mega-menu, a metafield swatch picker, a cart drawer that fights app scripts, or a stack where three widgets reintroduce traps after every theme update. That is foundation work, the same class of theme architecture we describe in The Anatomy of a High-Performance Shopify Theme.

Do not hire anyone whose only deliverable is an overlay plus a PDF certificate. Ask for a keyboard test recording, an ownership map, and theme diffs. If checkout or new customer accounts fail contrast you cannot edit, document the gap and report it to Shopify. Pretending an overlay covers hosted HTML will not survive a manual audit.

For a structured pass across theme, apps, and checkout extensions, start with a Shopify stack audit or theme development when the markup itself needs a rebuild.

Conclusion

Shopify accessibility is a storefront programme with a hard ownership line. You can fix the ten bugs that block most WCAG AA attempts on pages you render. You cannot make hosted checkout or new customer accounts perfect from theme.liquid, and you should stop paying overlay apps to pretend otherwise.

Start with a keyboard pass, tag every defect by owner, and remediate theme and catalogue first. Remove or replace apps that inject unnamed controls. Document Shopify-hosted exceptions in an accessibility statement, and keep retesting after theme updates and seasonal popups.

If you want that ownership map written against your live theme and app list, book a stack assessment and we will tell you which bugs you can close this sprint and which ones belong in a platform ticket.

Frequently Asked Questions

Most Shopify storefronts can reach a practical WCAG AA target on pages you control: theme templates, product content, cart, and most Online Store 2.0 sections. Hosted checkout and new customer accounts stay on Shopify's rendering path, and those surfaces can still fail contrast, focus, or label checks you cannot edit. Treat AA as a storefront programme with documented exceptions, not a single theme toggle.

No. Overlay widgets run after the page loads and cannot reliably rewrite the HTML that screen readers and scanners already parsed. Missing alt text, unlabelled buttons, and hover-only menus live in Liquid, product media, and app embeds. Use overlays only as a temporary user preference layer if you must, and fix the source markup if you want a durable WCAG AA result.

Shopify owns hosted checkout HTML. Merchants own branding choices that can drop contrast, plus any Checkout UI Extensions, cart attributes, and order-status Liquid they add. Shopify publishes a checkout accessibility conformance report and accepts reports at the contact listed there. If an audit flags checkout contrast or focus issues you cannot reach in the theme, log them with Shopify rather than installing an overlay on the storefront.

Empty or generic product image alt text is the failure scanners catch first, because Shopify outputs image.alt and many catalogues leave that field blank. Colour contrast on sale prices and muted palettes is the next cluster. Keyboard failures in menus, swatches, and drawers appear later because automated tools miss them. Start with alt text and contrast, then run a keyboard pass through search, product, cart, and customer login.

Tab through the homepage, a collection, a product with variants, the cart drawer, and customer login using only the keyboard. Confirm a visible focus ring on every control, that menus and swatches open with Enter or Space, and that Escape closes drawers. Add descriptive alt text in product media settings. Then run axe or Lighthouse as a first pass, knowing those tools miss keyboard traps and silent live updates.

Dawn, Refresh, and Sense are stronger starting points than most Theme Store premiums, and they still ship with predictable gaps once you change colours, add apps, or rebuild the header. No free theme is AA-complete after a brand palette and a reviews widget. Treat the theme as a baseline, then audit contrast, skip links, icon buttons, and any app that injects a popup or chat bubble.

The European Accessibility Act became enforceable for covered ecommerce services on 28 June 2025, with member-state penalties and scope rules that vary. WCAG 2.1 AA, plus the WCAG 2.2 criteria that affect tap targets, sticky headers, and authentication, is the technical target most teams use. Confirm whether your offer and markets sit in scope with counsel. This article is an engineering guide, not a legal opinion.

Bring in theme engineering when keyboard failures sit in custom mega menus, variant pickers, or cart drawers, or when apps keep reintroducing unlabelled widgets after you fix the theme. A structured Shopify stack audit maps which issues you own, which apps to remove, and which hosted surfaces to document. Overlay installs and Lighthouse-only scores are a weak brief for that work.

Related Articles