CRO · TECHNICAL · THEME · 19 JULY 2026 · 8 MIN READ
Accessibility on a product page, concretely
Not a policy statement and not an overlay. The eight components on a product page that break, the success criteria they break, and what to do instead.
Work component by component rather than page by page. On a product page the things that actually break are the variant picker, the gallery, the price and stock update, the cart drawer, the quantity and form controls, anything that appears on hover, and whatever an app injected. Each maps to a named WCAG success criterion, each is testable in a browser you already have, and most are fixed in the theme. Start with the keyboard: if you cannot buy the product using only Tab, Enter and the arrow keys, nothing further up the stack matters.
IN SHORT
- A variant swatch built from div elements has no accessible name, role or state — WCAG 2.2 success criterion 4.1.2 — and a colour-only selected state also fails 1.4.1 Use of Color.
- When a variant change updates price and availability, a screen reader is told nothing unless the update is announced; that is 4.1.3 Status Messages, level AA.
- Alt text must describe the image. Shopify's theme guidance is explicit that decorative images take an empty alt attribute rather than a filename.
- Opening a cart drawer without moving focus into it leaves keyboard users still on the page behind; Shopify requires focus order to match DOM order.
- WCAG 2.2 sets 4.5:1 contrast for normal text (1.4.3 AA), 3:1 for UI components and graphics (1.4.11 AA), and a 24 by 24 CSS pixel minimum target size (2.5.8 AA).
- Size guides and tooltips that appear on hover must be dismissible, hoverable and persistent under 1.4.13 — a tooltip that vanishes when you move towards it fails.
- Accessibility overlays sold as a one-line fix do not remediate the underlying markup. The money is better spent on the components.
Why the product page and not the whole site
A full-site audit produces a spreadsheet of several hundred issues, most of them on pages nobody buys from, and the usual outcome is that nothing gets fixed because the list is too long to start. The product page is the better unit of work: it carries the transaction, it shares almost all of its components with collection and cart pages, and it is where a blocked user is blocked from spending money rather than from reading a blog post.
It is also where accessibility and conversion stop being separate projects. A variant picker that does not respond to arrow keys is failing a screen reader user and irritating a power user on a laptop. A 4.5:1 contrast failure on the price is failing a low-vision customer and every customer reading outside in July.
Everything below is a component, a criterion, and a test you can run in a browser. Where a criterion is named, the number and level come from the WCAG 2.2 quick reference; where a theme rule is quoted, it comes from Shopify's own theme accessibility guidance.
The variant picker, which is where most of the damage is
Colour and size selectors are routinely built as a row of divs with a click handler and a CSS class for the current selection. That construction fails three criteria at once, and it is the single most common serious defect on a Shopify product page.
4.1.2 Name, Role, Value (level A) requires that components expose an accessible name, a role and their state. A div has no role, so assistive technology cannot say "Blue, radio button, selected, 2 of 6" — it says nothing useful at all. The fix is not ARIA; it is a real fieldset of input type="radio" elements with a legend naming the option, the labels visually replaced by swatches. You get keyboard operation, state and grouping without writing any of it.
1.4.1 Use of Color (level A) is failed by a selected state expressed only as a colour change. Add a ring, a tick or a border weight change so the selection survives greyscale — screenshot the picker, desaturate it, and see whether you can still tell which one is chosen.
1.4.11 Non-text Contrast (level AA) applies to the swatch outline itself: user interface components and graphical objects need "contrast ratio of at least 3:1 against adjacent color(s)". A pale grey ring on an off-white background is a selected state only the designer can see. This one bites hardest on white, cream and pale product colours, where the swatch and the page are nearly the same value.
A fourth problem is not a criterion but costs orders anyway: sold-out variants disabled with nothing but a lower opacity. Say the word. "Out of stock" in the label is worth more than any styling.
The gallery, and what alt text is for
Shopify's theme guidance puts it plainly: all images need alt attributes, "Product or content images feature alt text which describes the image", and decorative images use an empty alt attribute — alt="". Two failure modes follow from ignoring half of that.
The first is empty or filename alt text on the shots that carry information. A product photo showing the lining, the sole or the scale against a hand is describing something the copy does not, and that description is the alt text's job. Write what the picture adds, not the product name repeated six times — a gallery where every image reads "Navy wool coat" is technically compliant and practically useless.
The second is decorative images given descriptions. A lifestyle shot behind the gallery, a divider, a badge already announced in text — each one read aloud is an obstacle between a customer and the buy button. alt="" removes it from the accessibility tree entirely, which is the correct outcome.
Thumbnails need to be buttons, not clickable images, so that Enter and Space work and the current thumbnail exposes its selected state. If the gallery is a carousel, it needs keyboard controls that are visible on focus and a pause control if anything moves on its own — Shopify's guidance requires content be pausable, and auto-playing video be muted.
The silent update: price, stock and the cart count
Select a different size and three things change without a page load: the price, the availability message, and often the add-to-cart button label. A sighted user sees all three. A screen reader user is told nothing, because changing DOM content does not generate an announcement.
This is 4.1.3 Status Messages (level AA): status messages must be programmatically determinable without receiving focus. The mechanism is a live region — a container with an appropriate ARIA live role that exists in the DOM before the update, whose content is then replaced. Creating the element and its live role at the same moment is the classic mistake; many screen readers will not announce a region that was not being watched beforehand.
Three updates on a product page are worth wiring up, and no more. The price and availability when a variant changes. The confirmation when an item is added to the cart. Any inline validation message on a form. Announcing more than that produces a page that talks constantly, which people turn off, and a live region nobody hears is the same as no live region.
The cart drawer, which is a focus problem
Almost every modern theme adds to cart without navigating, and opens a drawer or modal. Done carelessly, the keyboard user presses Enter on Add to cart and nothing appears to happen: the drawer opened, focus stayed on the button behind it, and the next Tab press continues through the product page underneath — now covered by an overlay they cannot see.
Shopify's guidance is that "the keyboard focus order must match the DOM order" and that focus indicators be "visible and consistent on active elements", which is 2.4.7 Focus Visible (level AA). For an overlay that means four behaviours, all of them small: move focus into the drawer when it opens, keep Tab inside it while it is open, close it on Escape, and return focus to the element that opened it. That last one is the most frequently skipped and the most disorienting to miss — close the drawer and a keyboard user is dropped back at the top of the document, hunting for where they were.
The same rules apply to the size guide modal, the shipping information modal and the image lightbox. Build the behaviour once as a shared component and every overlay on the site inherits it. Native <dialog> handles most of this in current browsers if you are starting fresh.
Controls, forms and the things that only appear on hover
The quantity stepper is usually the smallest interactive element on the page and frequently the worst. 2.5.8 Target Size (Minimum), level AA in WCAG 2.2, sets a floor of 24 by 24 CSS pixels for targets. Plus and minus buttons drawn at 18 pixels miss it, and they miss it on exactly the device where most of your traffic is. They also need accessible names — "Increase quantity", not a bare glyph — and the field itself needs a label, which is 3.3.2 Labels or Instructions (level A).
Where the page validates anything — a personalisation field, a gift message, a postcode lookup — 3.3.1 Error Identification (level A) requires the error be identified and described in text, and 3.3.3 Error Suggestion (level AA) requires a correction be suggested where one is known. Shopify's guidance adds the implementation detail: focus is placed on the feedback message, and aria-describedby references the error container so the message is read with the field rather than left stranded above it.
Then the hover layer. Size charts, fabric notes, delivery estimates and discount explanations increasingly appear as tooltips, and 1.4.13 Content on Hover or Focus (level AA) sets three conditions: dismissible, hoverable, persistent. In practice that means Escape closes it without moving the pointer, the pointer can travel into the content without it disappearing, and it does not time out on its own. A size chart that vanishes when you move the mouse towards it fails all three and annoys everybody.
Two whole-page criteria round this off, both cheap to test. 1.4.4 Resize Text (AA) requires text to scale to 200% without loss of content or functionality, and 1.4.10 Reflow (AA) requires content to work at 320 CSS pixels wide without a second scroll direction. Set the browser to 320 pixels and zoom to 200% — sticky add-to-cart bars, price blocks and variant pickers are where things overlap first.
Apps, and why an overlay is not the answer
Reviews, size recommenders, upsell widgets, cookie banners and wishlist buttons all inject markup into the product page, and all of them can undo work you have paid for. Reviews are the usual culprit: star ratings rendered as images with no text alternative, a filter row of divs, a modal with no focus management. The review platform is a vendor decision, so treat accessibility as a procurement question and ask for the vendor's accessibility conformance report before signing, not after.
Which brings us to the product being sold hardest in this space. Accessibility overlays — a script you add to the theme that promises compliance — do not repair the markup underneath. They cannot invent an accessible name for a div, they cannot know which of your gallery images are decorative, and they cannot decide that a variant change should be announced. They sit on top of the page and attempt to reinterpret it at runtime, on top of the assistive technology the user already has and has already configured.
If your product page has the problems described above, an overlay leaves every one of them in place. The same annual spend put into the variant picker, the gallery and the cart drawer fixes them permanently, in code you own, for every user on every device. That is the honest recommendation even though it is the one that takes longer.
How to test it in an afternoon
Automated tooling is worth running and worth being honest about: it reliably finds contrast failures, missing alt attributes and missing form labels, and it cannot tell you whether the alt text is any good, whether focus goes somewhere sensible, or whether the price announcement made sense. Run it first because it is free, then do the part that requires a person.
The test that finds the most, in order:
- Unplug the mouse and buy something. Select a variant, change the quantity, add to cart, open the drawer, remove the item, reach checkout. Anywhere you get stuck is a defect, and you will typically get stuck twice.
- Do it again watching the focus ring. If it disappears, lands behind an overlay or jumps to the top of the document, note where.
- Turn on the screen reader already installed on your machine — VoiceOver on macOS, Narrator on Windows, TalkBack on Android — and listen to the variant picker and the add-to-cart confirmation. Fifteen minutes of this is more informative than any report.
- Set the viewport to 320 pixels, zoom to 200%, and look for overlap and horizontal scrolling.
- Screenshot the page and desaturate it. Anything you can no longer interpret is relying on colour alone.
The compliance question, answered carefully
Ecommerce is in scope for the European Accessibility Act — Directive (EU) 2019/882, which the European Commission lists e-commerce among its covered services and which member states had to transpose into national law by June 2022. What binds a particular seller is that member state's implementing law, including its enforcement regime and any small-business exemption, and those differ. Get that read by someone qualified in the markets you sell into rather than from a summary, this one included.
The more useful framing is that the components above are the ones a complaint would be about, and the ones a customer gives up on. The work is finite: a variant picker, a gallery, a live region, an overlay pattern, and a set of contrast and target-size corrections. That is a sprint, not a programme.
Questions this raises
What WCAG level should an ecommerce site target?
AA is the level regulators and procurement processes generally reference, and it is where the criteria that matter on a product page sit — 1.4.3 contrast at 4.5:1, 1.4.11 non-text contrast at 3:1, 2.4.7 focus visible, 2.5.8 target size at 24 by 24 CSS pixels, and 4.1.3 status messages. Confirm the standard named in the law that applies to you.
Are colour swatches on a product page accessible?
Rarely, as usually built. Divs with a click handler expose no name, role or state, failing 4.1.2, and a selected state shown only as a colour change fails 1.4.1 Use of Color. Build them as radio inputs in a fieldset with a legend, add a non-colour selected cue, and give the outline at least 3:1 contrast against the background.
Do accessibility overlay widgets make a store compliant?
No. An overlay script cannot supply an accessible name a div never had, decide which gallery images are decorative, or announce a variant price change. It layers a second interface over the assistive technology the user already runs. The same budget spent on the variant picker, gallery and cart drawer fixes the underlying markup permanently.
How do I make a variant change announced to a screen reader?
Use a live region: put a container with an appropriate ARIA live role in the DOM before any update happens, then replace its contents with the new price and availability. WCAG 2.2 criterion 4.1.3 requires status messages to be determinable without receiving focus. Creating the region at the moment of the update often results in nothing being announced.
What alt text should a product image have?
Describe what the image shows that the copy does not — the lining, the sole, the scale. Shopify's theme guidance asks for alt text that describes the image, and an empty alt attribute for decorative images. Repeating the product name across every gallery shot passes an automated check and helps nobody.
Does accessibility work improve conversion?
The overlap is real rather than incidental: contrast, target size, focus visibility, clear error messages and keyboard operation all affect customers who have no disability but are on a phone, in sunlight or in a hurry. Treat it as usability work with a legal floor rather than as a compliance exercise with a usability side effect.
NEXT STEP
Free store audit
A senior Shopify engineer reviews your storefront, theme performance and checkout, then sends a prioritised list of fixes.
