Skip to content

U.S. e-commerce accessibility / Case 03

Building an accessibility improvement and maintenance program for a Shopify storefront

A US Shopify retailer needed a repeatable way to improve and maintain storefront accessibility as the site evolved. The work combined source-level theme remediation, representative WCAG-oriented testing, manual review, dated evidence, an Accessibility Statement, and an ongoing monitoring workflow.

WCAG 2.1 AAShopifyWAVEaxe DevToolsLighthouseKeyboard QAAccessibility improvementAccessibility monitoring

A developer's implementation guide.

This case study shares accessibility improvement, testing, and maintenance work from a developer's perspective. It uses WCAG and platform guidance as technical references, but it is not legal advice or a certification that every accessibility requirement has been met.

What this solved for the business or user

The goal was not to make one scanner show a green score. The business needed a practical process showing what was tested, which issues were confirmed, how the underlying theme code was improved, what was retested, what remained open, and when the storefront should be reviewed again. Automated results were treated as useful engineering evidence, not as a complete accessibility certification.

What was happening

The storefront was an active Shopify implementation with reusable Liquid components, JavaScript-driven drawers and menus, product forms, responsive states, hosted checkout, and third-party apps. Because the site changed regularly through theme releases, app updates, campaigns, content changes, and vendor widgets, accessibility could not be treated as a one-time task. The work therefore became an ongoing improvement and maintenance process built around representative customer journeys, reusable components, documented fixes, and scheduled regression reviews.

Why the obvious solution was not enough

Automated accessibility tools were useful for finding reproducible markup, contrast, naming, and structural problems, but they could not prove complete keyboard usability, focus behavior, screen-reader output, error recovery, or dynamic-widget behavior. Tool results could also disagree: a page could show 0 automatic axe issues while WAVE still exposed a broken ARIA reference that required DOM inspection. The process therefore had to separate confirmed technical defects from scanner alerts that only required human review, distinguish theme-owned code from third-party or platform surfaces, and keep unresolved manual checks visible instead of treating a clean scan as the end of the work.

How the solution works

  1. Establish an accessibility baseline in the Shopify theme. Review Liquid and JavaScript for form-label associations, accessible names on buttons and links, ARIA relationships, keyboard behavior, focus management and focus traps, color contrast, semantic HTML, heading structure, and invalid description-list markup such as incorrect <dl>, <dt>, and <dd> usage.
  2. Reproduce each reported or discovered barrier before changing code. Inspect the rendered DOM, identify the affected component and state, confirm the technical issue, then document the root cause, fix, retest result, and current status.
  3. Fix defects at the source component rather than hiding symptoms with CSS. One documented cart-drawer defect used aria-labelledby="csc-drawer-title" even though no element had that ID. The visible 'Your Bag' heading was given the matching ID so the dialog had a real accessible-name relationship.
  4. Correct data-driven navigation output. A desktop mega-menu CTA could render as an empty link when its metaobject title and URL were blank. The Liquid logic was changed to render the CTA only when both values exist, and repeated ID-based styling was replaced with a reusable class where appropriate.
  5. Treat scanner alerts as triage items, not automatic failures. Redundant links and Shopify noscript fallbacks were reviewed in context; very-small-text alerts were moved to manual zoom and readability verification instead of being changed only to silence the tool.
  6. Add an Accessibility Statement page with a working reporting path so customers have a documented way to report barriers and the business has an operational feedback channel.
  7. Use multiple automated signals. WAVE supports visual DOM debugging and contextual alert review, axe DevTools provides WCAG-oriented automated rule checks, and Lighthouse provides an additional accessibility score and regression signal.
  8. Audit representative templates and journeys instead of blindly scanning every URL. Coverage included the homepage, collections, primary and secondary product templates, cart drawer, hosted checkout, account, contact, FAQ and returns, blog content, policy pages, the Accessibility Statement, 404 behavior, and third-party controls where they render.
  9. Capture responsive evidence where behavior changes. Desktop and mobile states were checked for navigation, product templates, forms, layout, and other responsive interactions rather than assuming a desktop result automatically applied to mobile.
  10. Keep a structured manual-validation backlog for Tab and Shift+Tab order, Enter and Space activation, Escape behavior, visible focus, hidden-content focusability, cart-drawer focus trapping and restoration, 200% zoom and reflow, form errors, accessible names, dynamic announcements, and screen-reader spot checks.
  11. Record every audit cycle as evidence: tested URL or flow, device or context, tool, issue type, root cause, remediation, current status, retest result, and date. Screenshots or exports are retained with the corresponding remediation ticket or maintenance record.
  12. Build a recurring regression workflow. Re-run WAVE, axe, and Lighthouse after material theme changes, app additions, new sections, or third-party script updates; retest the same representative customer journeys; compare new findings against the prior review; and keep unresolved third-party or manual items visible.
  13. Use ownership-aware remediation. Theme-owned HTML, Liquid, CSS, and JavaScript issues are fixed in the storefront code; vendor-owned iframe, hosted-checkout, or app-script findings are documented separately and escalated to the platform or vendor when a theme-only fix is not possible.
A maintenance record is more useful than a one-time score
type FindingStatus =
  | 'open'
  | 'fixed'
  | 'retested'
  | 'manual-review'
  | 'third-party';

type AccessibilityFinding = {
  page: string;
  component: string;
  standardTarget: 'WCAG 2.1 AA';
  source: 'WAVE' | 'axe' | 'Lighthouse' | 'manual';
  issue: string;
  rootCause: string;
  remediation: string;
  status: FindingStatus;
  testedAt: string;
};

const representativeCoverage = [
  'homepage',
  'collection',
  'primary-product',
  'secondary-product',
  'cart-drawer',
  'checkout',
  'account',
  'contact',
  'faq-and-returns',
  'blog',
  'static-content',
  'policies-and-accessibility-statement',
  '404',
];

const remediationLog: AccessibilityFinding[] = [
  {
    page: 'homepage',
    component: 'cart drawer',
    standardTarget: 'WCAG 2.1 AA',
    source: 'WAVE',
    issue: 'Broken ARIA reference',
    rootCause: 'aria-labelledby referenced a missing title ID',
    remediation: 'Attach the referenced ID to the visible drawer heading',
    status: 'retested',
    testedAt: '2026-07-29',
  },
];

// Release rule: a clean automated scan closes only the automated
// finding. Manual keyboard, focus, zoom/reflow and screen-reader
// checks remain separate requirements and are never auto-cleared.

What should be verified before shipping

  • Verify each confirmed finding has an exact page or flow, component, test method, date, root cause, remediation, status, and retest result instead of only a screenshot score.
  • Reproduce WAVE or axe findings in the rendered DOM and trace them to the Liquid or JavaScript source before changing the theme.
  • For ARIA relationships, confirm every aria-labelledby, aria-describedby, and aria-controls target exists, is unique, and points to the intended visible or programmatic element.
  • Test all modal, drawer, and menu interactions with keyboard only: logical Tab order, Enter and Space activation, Escape dismissal, visible focus, focus containment where required, and focus restoration after close.
  • At 200% browser zoom, verify the storefront remains usable without clipped controls, overlapping content, or loss of information; review small-text alerts in that context.
  • For forms and product controls, verify visible or programmatic labels, fieldset and legend grouping where required, meaningful error text, and appropriate announcement of validation or dynamic state changes.
  • Retest representative desktop and mobile states after remediation. A component that is shared globally should be checked in the states most likely to exercise different responsive or dynamic behavior.
  • Keep WAVE alerts classified as accepted, fixed, or manual-review. Do not convert alert count into a failure count without inspecting the context.
  • Recheck third-party components such as reviews, size guides, recommendations, chat, marketing forms, and other app-injected controls after vendor updates because their markup can change independently of the theme.
  • Keep reporting conservative: automated results can demonstrate improvement and regression coverage, but they do not replace complete manual WCAG evaluation or assistive-technology testing.

What changed

The work moved from isolated accessibility fixes into a documented improvement and maintenance process. The April baseline recorded a WAVE AIM score of 9.6/10 with 0 errors and 0 contrast errors, Lighthouse accessibility around 94–97 depending on the run, and 0 automatic axe issues in the captured homepage scan. By the July 29 evidence cycle, the review covered 20 live URLs or hosted flows plus the global cart drawer, included 84 final evidence screenshots, showed 0 automatic axe issues on all 16 pages or flows with supplied axe evidence, and recorded Lighthouse accessibility scores of 97–100 on tested public pages. Follow-up work remained visible, including specific ARIA, contrast, heading, form-grouping, keyboard, and screen-reader checks. The result was a more accessible storefront and a repeatable process for catching regressions as the site changes, not a claim that future releases can never introduce new issues.

Reusable lesson

Accessibility works best as an ongoing engineering discipline: identify barriers, improve the source component, verify behavior with more than one method, preserve evidence, keep unresolved manual and third-party items visible, and repeat representative checks after meaningful changes.

How I would evaluate this today

Recommended operating model: keep dated evidence for the same representative templates, run an additional review after material theme, app, or script changes, maintain the Accessibility Statement and reporting path, assign theme-owned findings to engineering, escalate vendor-owned findings when necessary, and schedule periodic manual assistive-technology testing. This case study is a developer-focused technical guide based on implementation work. It is not legal advice and does not certify that a website meets every accessibility or regulatory requirement.

Official documentation and standards