August 2026 19 min read Technical Guide

15 Common WCAG Accessibility Issues on Shopify Stores (And How to Fix Them)

Not generic WCAG explanations — Shopify-specific violations. What each one looks like in code, why it happens, who it affects, and how to spot it on your own store.

You ran an accessibility audit on your Shopify store.

You got the results back.

"15 WCAG violations found."

Now what?

Which violations are critical? Which are easy to fix? Which will hurt your business the most?

This guide walks through the 15 most common WCAG 2.1 violations found on Shopify stores.

Not generic WCAG explanations. Shopify-specific violations. What they look like. Why they happen. What impact they have. How to spot them.

By the end, you'll understand exactly what's wrong with your store and what needs to be fixed first.

Quick Overview: The 15 Most Common Shopify WCAG Violations

Critical Fix first

  1. Missing Accessible Names
  2. Keyboard Traps
  3. Inaccessible Navigation
  4. Product Variants Not Labeled
  5. Missing Form Labels

High Fix second

  1. Incorrect ARIA Implementation
  2. Missing Focus Indicators
  3. Modal Accessibility Issues
  4. Cart Drawer Keyboard Trap
  5. Inaccessible Carousels

Medium Fix third

  1. Color Contrast Failures
  2. Missing Image Alt Text
  3. Poor Error Messages
  4. Heading Hierarchy Issues
  5. Third-Party App Violations
WAVE scanner results on a non-compliant Shopify store showing 28 errors, 15 contrast errors, 22 alerts, 31 features and 19 structural elements. Violation markers across the page flag empty links in the navigation, low contrast on hero text and buttons, missing alt text on product images, a missing form label on the newsletter signup and a possible heading order issue.

Critical Violations (Fix These FIRST)

Violation #1: Missing Accessible Names (WCAG 4.1.2)

What it is: Interactive elements (buttons, links, form fields) don't have clear, descriptive names that screen readers can read.

Why it happens on Shopify: Developers use icons without text. Or use vague button labels like "Click here" or "Submit".

accessible names
<!-- BAD - Icon button with no accessible name --> <button>🛒</button> <!-- BAD - Vague button text --> <button>Submit</button> <!-- GOOD - Descriptive accessible name --> <button aria-label="Add to Cart"> <svg>🛒</svg> </button> <!-- GOOD - Clear button text --> <button>Add to Cart</button>

Why it matters: Screen reader users hear nothing (or just "button") when they encounter a nameless button. They don't know what it does. They can't interact with your store.

Impact on blind users

How to spot it:

  1. Go to your Shopify store
  2. Right-click on a button with just an icon
  3. Click "Inspect"
  4. Look for aria-label or text inside button
  5. If neither exists: Missing accessible name

How to fix:

fix · icon and submit buttons
<!-- Fix icon buttons --> <button aria-label="Add to Cart"> <svg class="cart-icon">...</svg> </button> <!-- Or add text --> <button> <svg class="cart-icon">...</svg> Add to Cart </button> <!-- Fix form submit --> <button type="submit" aria-label="Submit Order Form"> Submit </button>

Violation #2: Keyboard Traps (WCAG 2.1.2)

What it is: User presses Tab to navigate, but gets stuck. Can't escape certain elements with keyboard.

Why it happens on Shopify: Custom JavaScript for modals, dropdown menus, or overlays doesn't handle keyboard focus properly.

How it looks:

  1. User presses Tab to navigate
  2. Focus gets stuck in a modal or menu
  3. User presses Tab repeatedly but nothing happens
  4. User presses Escape but modal doesn't close
  5. User is trapped

Why it matters: Motor-disabled users navigate with keyboard only. If they get trapped, they can't continue shopping.

Impact on motor-disabled users

How to spot it:

  1. Go to your Shopify store
  2. Put your mouse away (don't use it)
  3. Press Tab through entire page
  4. Try to navigate modal/popup with keyboard
  5. Try to close with Escape key
  6. If you get stuck: Keyboard trap

How to fix:

modal focus management
// Trap focus inside modal when open const modal = document.getElementById('modal'); const closeBtn = modal.querySelector('.close-btn'); function openModal() { modal.style.display = 'block'; modal.setAttribute('aria-hidden', 'false'); closeBtn.focus(); // Move focus into modal } // Allow Escape to close and return focus document.addEventListener('keydown', function(e) { if (e.key === 'Escape' && modal.style.display === 'block') { modal.style.display = 'none'; modal.setAttribute('aria-hidden', 'true'); document.getElementById('openBtn').focus(); // Return focus } });

Violation #3: Inaccessible Navigation (WCAG 2.1.1)

What it is: Navigation menus don't work with keyboard. Dropdown menus only work with mouse hover.

Why it happens on Shopify: Theme CSS uses hover states only. JavaScript only listens for mouse clicks.

hover vs focus-within
/* BAD - Only works with mouse hover */ nav ul li:hover > ul { display: block; } /* GOOD - Works with keyboard focus too */ nav ul li:focus-within > ul { display: block; }

Why it matters: Keyboard users can't open dropdown menus. Can't see product categories. Can't navigate site.

Impact

How to spot it:

  1. Put mouse away
  2. Press Tab through navigation
  3. Try to open dropdown with Enter or Space
  4. If dropdown doesn't open: Inaccessible navigation

How to fix:

keyboard accessible navigation
<nav> <ul role="menubar"> <li role="none"> <a href="/products" aria-haspopup="true" aria-expanded="false" id="productsBtn"> Products </a> <ul role="menu" aria-labelledby="productsBtn"> <li role="none"><a href="/men">Men</a></li> <li role="none"><a href="/women">Women</a></li> </ul> </li> </ul> </nav> <script> const menuBtn = document.getElementById('productsBtn'); menuBtn.addEventListener('keydown', function(e) { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); this.setAttribute('aria-expanded', this.getAttribute('aria-expanded') === 'true' ? 'false' : 'true'); } }); </script>

Violation #4: Product Variants Not Labeled (WCAG 1.3.1)

What it is: Size/color options presented as clickable swatches without text labels. Screen reader users don't know what they're clicking.

Why it happens on Shopify: Theme shows only colored boxes or pictures without accompanying text.

variant labelling
<!-- BAD - No labels for variant options --> <div class="variant-selector"> <div class="color" style="background: red;"></div> <div class="color" style="background: blue;"></div> <div class="color" style="background: green;"></div> </div> <!-- GOOD - Text labels included --> <div class="variant-selector"> <label> <input type="radio" name="color" value="red"> <span>Red</span> </label> <label> <input type="radio" name="color" value="blue"> <span>Blue</span> </label> <label> <input type="radio" name="color" value="green"> <span>Green</span> </label> </div>

Why it matters: Screen reader users hear nothing when they encounter color swatches. Colorblind users can't tell colors apart. Users don't know what they're selecting.

Impact

How to spot it: Go to a product page, look at the size/color selector. If it's only boxes or swatches with no text: unlabeled variants.

How to fix:

fix · always include text labels
<div class="size-selector"> <label> <input type="radio" name="size" value="small"> Small </label> <label> <input type="radio" name="size" value="medium"> Medium </label> <label> <input type="radio" name="size" value="large"> Large </label> </div>

Violation #5: Missing Form Labels (WCAG 1.3.1)

What it is: Form fields don't have associated labels. Screen reader users don't know what to enter.

Why it happens on Shopify: Developers use placeholder text instead of labels. Or forgot to add labels entirely.

form labels
<!-- BAD - No label --> <input type="email" placeholder="Enter email"> <!-- BAD - Label not connected to field --> <label>Email</label> <input type="email"> <!-- GOOD - Label connected to input --> <label for="email">Email Address</label> <input type="email" id="email" required>

Why it matters: Screen reader users can't hear what field they're in. Can't complete forms. Can't checkout.

Impact

How to spot it:

  1. Go to checkout page
  2. Right-click on form field
  3. Inspect code
  4. Look for <label> tag with matching for attribute
  5. If missing: Form label violation

How to fix:

fix · proper form labels
<label for="firstName">First Name</label> <input type="text" id="firstName" required> <label for="email">Email Address</label> <input type="email" id="email" required> <label for="address">Street Address</label> <input type="text" id="address" required>
Shopify product page with accessibility violations marked: missing alt text on product images so screen reader users get no context, low colour contrast on the price and body text, unlabeled colour and size variants, and quantity form controls that use icons with no accessible label.

High Violations (Fix These SECOND)

Violation #6: Incorrect ARIA Implementation (WCAG 4.1.2)

What it is: ARIA attributes are used incorrectly, confusing screen readers instead of helping.

Why it happens on Shopify: Developers add ARIA without understanding how it works. Or copy-paste incorrect implementations.

common ARIA mistakes
<!-- BAD - Wrong role --> <div role="button" onclick="doSomething()">Click me</div> <!-- BAD - Unnecessary ARIA --> <button role="button">Submit</button> <!-- already has implicit role --> <!-- BAD - Contradictory ARIA --> <div role="button" aria-hidden="true">Add to Cart</div> <!-- GOOD - Correct ARIA usage --> <button onclick="doSomething()">Click me</button> <!-- GOOD - ARIA only when needed --> <div role="button" aria-label="Close menu" onclick="closeMenu()">×</div>

Why it matters: Incorrect ARIA confuses screen readers. Users hear wrong information. Buttons don't work as expected.

Impact

How to fix: Use semantic HTML first (button, link, form) because they have implicit roles. Only use ARIA when HTML can't do the job.

fix · semantic HTML first
<!-- Prefer semantic HTML --> <button>Add to Cart</button> <a href="/products">Shop</a> <input type="email"> <!-- Use ARIA only when necessary --> <div role="tab" aria-selected="true" aria-controls="panel1"> Product Details </div> <div id="panel1" role="tabpanel" aria-labelledby="tab1"> Content here </div>

Violation #7: Missing Focus Indicators (WCAG 2.4.7)

What it is: Keyboard users can't see which element currently has focus (no visible outline/highlight).

Why it happens on Shopify: Developers remove default focus outline with CSS because it looks ugly.

the anti-pattern
/* BAD - Removes all focus indicators */ *:focus { outline: none; }

Why it matters: Keyboard users navigate by pressing Tab. They need to see which element is currently focused. Without visible focus, they're lost.

Impact

How to fix:

fix · custom focus indicator
/* GOOD - Custom focus indicator */ button:focus { outline: 3px solid #0066cc; outline-offset: 2px; } /* Or use focus-visible for keyboard only */ button:focus-visible { outline: 3px solid #0066cc; } /* Never do this */ button:focus { outline: none; /* DON'T DO THIS */ }

Violation #8: Modal Accessibility Issues (WCAG 2.1.2)

What it is: Modal dialogs (popups, lightboxes) don't trap focus properly, announce to screen readers, close with Escape key, or return focus after closing.

Why it happens on Shopify: Modals built with custom JavaScript without accessibility in mind.

How to spot it:

  1. Click button that opens modal
  2. Modal appears
  3. Press Tab — does focus move into modal?
  4. Can you close with Escape key?
  5. After closing, does focus return to button?

If any answer is NO: Modal accessibility issue

How to fix:

accessible modal structure
<div id="modal" role="dialog" aria-labelledby="modalTitle" aria-hidden="false"> <div class="modal-content"> <h2 id="modalTitle">Product Options</h2> <p>Choose your options below:</p> <button id="closeBtn" aria-label="Close dialog">×</button> </div> </div> <script> const modal = document.getElementById('modal'); const closeBtn = document.getElementById('closeBtn'); const openBtn = document.getElementById('openBtn'); // Open modal and move focus openBtn.addEventListener('click', function() { modal.setAttribute('aria-hidden', 'false'); closeBtn.focus(); }); // Close modal with button click or Escape key function closeModal() { modal.setAttribute('aria-hidden', 'true'); openBtn.focus(); // Return focus } closeBtn.addEventListener('click', closeModal); document.addEventListener('keydown', function(e) { if (e.key === 'Escape') { closeModal(); } }); </script>

Violation #9: Cart Drawer Keyboard Trap (WCAG 2.1.2)

What it is: Cart drawer opens but keyboard focus stays outside it. Users can't Tab into the drawer.

Specific case of keyboard traps but common enough to highlight.

Why it happens: Cart drawer built with JavaScript that doesn't manage focus.

How to fix:

cart drawer focus
// When cart drawer opens, move focus into it const cartBtn = document.getElementById('cart-button'); const cartDrawer = document.getElementById('cart-drawer'); const closeDrawerBtn = cartDrawer.querySelector('.close-btn'); cartBtn.addEventListener('click', function() { cartDrawer.style.display = 'block'; cartDrawer.setAttribute('aria-hidden', 'false'); closeDrawerBtn.focus(); // Move focus into drawer }); // Allow Escape to close and return focus document.addEventListener('keydown', function(e) { if (e.key === 'Escape' && cartDrawer.style.display === 'block') { cartDrawer.style.display = 'none'; cartDrawer.setAttribute('aria-hidden', 'true'); cartBtn.focus(); // Return focus to cart button } });

Violation #10: Inaccessible Carousels (WCAG 2.1.1)

What it is: Image carousels/sliders can't be controlled with keyboard. Only work with mouse.

Why it happens: Carousel JavaScript only handles mouse clicks on prev/next arrows.

How to fix:

accessible carousel
<div class="carousel" role="region" aria-label="Product images"> <div class="carousel-container"> <img src="image1.jpg" alt="Product front view"> <img src="image2.jpg" alt="Product back view" style="display: none;"> </div> <button aria-label="Previous image">←</button> <button aria-label="Next image">→</button> <div class="carousel-controls"> <button>Image 1 (current)</button> <button>Image 2</button> <button>Image 3</button> </div> </div> <script> let currentSlide = 0; const slides = document.querySelectorAll('.carousel img'); // Arrow keys navigate carousel document.addEventListener('keydown', function(e) { if (e.key === 'ArrowLeft') { currentSlide = (currentSlide - 1 + slides.length) % slides.length; showSlide(currentSlide); } if (e.key === 'ArrowRight') { currentSlide = (currentSlide + 1) % slides.length; showSlide(currentSlide); } }); function showSlide(n) { slides.forEach(slide => slide.style.display = 'none'); slides[n].style.display = 'block'; } </script>
Shopify checkout page with four violations annotated: missing form labels where inputs rely on placeholders instead of visible labels, poor colour contrast on placeholder and secondary text, no focus indicators on interactive elements, and keyboard traps where focus can become stuck in modal-like sections with no clear way out.

Medium Violations (Fix These THIRD)

Violation #11: Color Contrast Failures (WCAG 1.4.3)

What it is: Text color too similar to background. Low-vision users can't read it.

Standard: Text must have 4.5:1 contrast ratio minimum

Common Shopify failures

How to fix: Change text to darker color.

contrast fix
/* BEFORE - Fails */ .product-description { color: #999; /* Light gray */ background: white; } /* AFTER - Passes */ .product-description { color: #333; /* Dark gray */ background: white; }

Violation #12: Missing Image Alt Text (WCAG 1.1.1)

What it is: Images have no alternative text. Blind users can't see products.

Common on Shopify: Product images, hero images, banners

How to fix:

alt text
<!-- BAD - No alt text --> <img src="product.jpg"> <!-- GOOD - Descriptive alt text --> <img src="product.jpg" alt="Navy blue 100% cotton crew neck t-shirt, front view, size medium">

Violation #13: Poor Error Messages (WCAG 3.3.1)

What it is: Error messages don't explain what went wrong.

User types invalid email, gets message: "Error". What error? How do they fix it?

How to fix:

error messaging
<!-- BAD --> <div class="error">Invalid</div> <!-- GOOD --> <div class="error" role="alert"> Email must be in format: name@example.com </div>

Violation #14: Heading Hierarchy Issues (WCAG 1.3.1)

What it is: Headings don't follow logical hierarchy (H1 → H2 → H3). Jumps from H1 directly to H3. Screen reader users get confused.

How to fix:

heading hierarchy
<!-- BAD - Skips H2 --> <h1>Products</h1> <h3>Clothing</h3> <!-- Wrong - should be H2 --> <!-- GOOD - Proper hierarchy --> <h1>Products</h1> <h2>Clothing</h2> <h3>T-Shirts</h3> <h3>Pants</h3> <h2>Accessories</h2>

Violation #15: Third-Party App Violations (WCAG multiple)

What it is: Installed Shopify apps introduce accessibility violations.

Common culprits

How to fix: Test every app. Remove apps that break accessibility. Find accessible alternatives.

Before and after accessibility remediation on a product page. Before: missing alt text, insufficient colour contrast, poor content structure, colour swatches without labels, missing form labels, low contrast call to action and missing focus states, which excludes users and creates compliance risk. After: descriptive alt text, strong colour contrast, clear content structure, labels for colour choices, proper field labels, high contrast buttons and visible focus states, producing an inclusive experience and reduced compliance risk.

These Are the Issues Our Manual Shopify Accessibility Audit Tests

Every violation above is what we test for in our professional accessibility audits.

Why manual testing matters:

Automated tools catch

70% of violations

  • Obvious issues only

Manual testing catches

95%+ of violations

  • Complex interactions included

Manual testing includes

Our audit process

  1. Automated scan — finds obvious violations
  2. Keyboard testing — tests keyboard navigation
  3. Screen reader testing — tests with NVDA/JAWS
  4. Manual code review — checks implementation quality
  5. Detailed report — lists all violations with fixes
  6. Remediation guidance — priority + timeline

Priority: Which to Fix First

Week 1-2 Critical

  • Missing form labels
  • Keyboard traps
  • Inaccessible navigation
  • Product variants without labels
  • Missing accessible names

Fix these first because they block access to core functionality.

Week 2-3 High

  • Incorrect ARIA
  • Missing focus indicators
  • Modal accessibility
  • Cart drawer issues
  • Inaccessible carousels

Week 3-4 Medium

  • Color contrast
  • Missing alt text
  • Poor error messages
  • Heading hierarchy
  • Third-party app violations

Summary: The 15 Most Common Shopify WCAG Violations

These violations are found on 90%+ of non-compliant Shopify stores.

Most are easy to fix (1-4 hours each). Some require professional help. All are critical for ADA compliance.

Know which violations YOUR store has?

Professional audit identifies all 15 violations (and more) specific to your site. Includes specific fix recommendations and timeline.

Get your free professional accessibility audit →

Next Steps

  1. Know your violations: Get an audit
  2. Prioritize fixes: Critical violations first
  3. Execute remediation: Fix issues according to priority
  4. Verify compliance: Re-audit after fixes
  5. Maintain: Test quarterly for new violations

This process takes 2-4 weeks with professional help. Or 4-8 weeks if doing it yourself.

The sooner you start, the sooner you're compliant.

Ready to fix these violations?

We identify all violations and implement fixes. 100% WCAG 2.1 AA compliance in 10-14 days. Includes documentation proving compliance.

Get comprehensive Shopify accessibility remediation →

Want to understand the legal requirements?

Read our complete WCAG 2.1 requirements guide →

This explains exactly what courts require for ADA compliance.

Final Thought

These 15 violations account for 90% of accessibility problems on Shopify stores.

They're also 90% fixable.

Stop worrying. Start fixing.

Your disabled customers will thank you.