How to Fix Common Accessibility Issues on Shopify: A Technical Guide
After scanning thousands of Shopify stores, we have identified the 10 most frequently occurring WCAG 2.1 AA violations. This guide explains each violation, why it matters, how to fix it manually in your theme code, and whether AccessComply can resolve it automatically.
1. Missing Alternative Text on Images
WCAG Criterion: 1.1.1 Non-text Content | axe-core Rule: image-alt | Severity: Critical
Images without alt attributes are invisible to screen reader users. Product images, banners, and icons all need descriptive text alternatives. This is the single most common violation on Shopify stores because themes often render product images without pulling in the alt text from the Shopify admin.
Manual fix: In your Liquid template, ensure image tags include the alt attribute:
{% assign img_alt = image.alt | escape | default: product.title | escape %}
<img src="{{ image | img_url: '640x' }}" alt="{{ img_alt }}" width="640" height="640">
AccessComply auto-fix: Yes. The AltTextAgent uses AI to generate contextual descriptions for product and content images, writing them directly into your theme files.
2. Insufficient Color Contrast
WCAG Criterion: 1.4.3 Contrast (Minimum) | axe-core Rule: color-contrast | Severity: Serious
Text that does not meet the 4.5:1 contrast ratio against its background is difficult or impossible to read for users with low vision or color deficiencies. This violation frequently appears in sale badges, footer text, placeholder text, and secondary navigation links.
Manual fix: Adjust the color values in your CSS. For example, change light gray text on a white background from color: #999 to color: #595959 to achieve 4.5:1 against white.
AccessComply auto-fix: Yes. The ContrastAgent calculates the minimum color adjustment needed to meet the required ratio while preserving your design intent.
3. Missing Form Labels
WCAG Criterion: 1.3.1 Info and Relationships | axe-core Rule: label | Severity: Critical
Form inputs without associated labels are announced as "edit text" by screen readers with no indication of what information to enter. This is especially problematic in checkout, account login, and newsletter signup forms.
Manual fix: Wrap each input in a label or use the for attribute:
<label for="email">Email address</label>
<input id="email" type="email" name="customer[email]">
AccessComply auto-fix: Yes. The FormLabelAgent identifies unlabeled inputs and adds the appropriate label elements or ARIA attributes.
4. Icon Buttons Without Accessible Names
WCAG Criterion: 4.1.2 Name, Role, Value | axe-core Rule: button-name | Severity: Critical
Cart icons, search icons, and hamburger menus that contain only an SVG icon with no text alternative announce as "button" to screen readers — providing no context. Users with visual impairments cannot tell what the button does.
Manual fix: Add aria-label to icon buttons and aria-hidden to the decorative SVG:
<button type="button" aria-label="Open cart">
<svg aria-hidden="true" focusable="false">
<!-- cart SVG path -->
</svg>
</button>
AccessComply auto-fix: Yes. The AriaLabelAgent identifies nameless interactive elements and generates contextually appropriate ARIA labels.
5. Missing Skip Navigation
WCAG Criterion: 2.4.1 Bypass Blocks | axe-core Rule: bypass | Severity: Serious
Without a skip navigation link, keyboard users must tab through your entire header — logo, navigation links, account icon, cart icon — on every page before reaching the main content. For stores with extensive navigation, this creates a frustrating barrier.
Manual fix: Add a skip link as the first element in layout/theme.liquid:
<a href="#main-content" class="skip-link">Skip to main content</a>
With CSS to show it on focus:
.skip-link {
position: absolute;
top: -40px;
left: 0;
background: #000;
color: #fff;
padding: 8px 16px;
z-index: 9999;
text-decoration: none;
}
.skip-link:focus {
top: 0;
}
Add the target ID to your main content section: <main id="main-content" tabindex="-1">.
AccessComply auto-fix: Yes. The SkipNavAgent adds the skip link and matching target ID to the correct locations in your theme files.
6. Missing Page Language
WCAG Criterion: 3.1.1 Language of Page | axe-core Rule: html-has-lang | Severity: Serious
Screen readers use the lang attribute on the <html> element to determine which language rules and pronunciation to use. Missing or incorrect language attributes cause screen readers to mispronounce content, which is particularly severe for non-English stores.
Manual fix: In layout/theme.liquid, ensure:
<html lang="{{ request.locale.iso_code }}">
The request.locale.iso_code Liquid variable provides the correct ISO 639-1 language code (e.g., en, fr, de) based on the active store locale.
AccessComply auto-fix: Yes. The LanguageAgent detects missing or incorrect lang attributes and applies the fix.
7. Duplicate IDs
WCAG Criterion: 4.1.1 Parsing | axe-core Rule: duplicate-id | Severity: Serious
When the same id attribute value appears multiple times on a page, ARIA attributes that reference those IDs (like aria-labelledby and aria-describedby) break. Screen readers and assistive technologies rely on unique IDs to build accurate accessibility trees.
Shopify themes commonly generate duplicate IDs when the same section is rendered multiple times or when a product grid generates item IDs without unique suffixes.
Manual fix: In Liquid templates that generate IDs dynamically, include a unique identifier:
<div id="product-{{ product.id }}-{{ forloop.index }}">
AccessComply auto-fix: Yes. The DuplicateIdAgent identifies duplicate IDs and adds unique suffixes based on context.
8. Missing Focus Indicators
WCAG Criterion: 2.4.7 Focus Visible | axe-core Rule: focus-visible | Severity: Serious
Many Shopify themes use outline: none or outline: 0 in their CSS to remove the default browser focus ring, often for aesthetic reasons. This makes keyboard navigation invisible — keyboard users cannot see which element is currently focused.
Manual fix: Remove outline: none from your CSS or replace it with a visible custom focus style:
/* Remove this: */
*:focus { outline: none; }
/* Add this instead: */
*:focus-visible {
outline: 2px solid #F97316;
outline-offset: 2px;
border-radius: 2px;
}
AccessComply auto-fix: Yes. The FocusAgent removes outline suppression and adds a visible focus style.
9. Missing Frame Titles
WCAG Criterion: 4.1.2 Name, Role, Value | axe-core Rule: frame-title | Severity: Serious
Inline frames (<iframe>) without title attributes announce as "frame" to screen readers with no description of their content. Shopify stores commonly embed iframes for reviews (Trustpilot, Judge.me), maps, videos, and chat widgets.
Manual fix: Add a descriptive title to all iframes:
<iframe src="https://widgets.trustpilot.com/..." title="Trustpilot reviews"></iframe>
AccessComply auto-fix: Yes. The FrameTitleAgent identifies untitled iframes and generates appropriate titles based on the iframe source.
10. Table Structure Issues
WCAG Criterion: 1.3.1 Info and Relationships | axe-core Rule: td-headers-attr | Severity: Serious
Data tables without <th> elements or proper scope attributes are unnavigable for screen reader users. Table cells are read in sequence with no indication of what column or row header they belong to. Shopify stores with size charts, comparison tables, or specification sheets commonly have this issue.
Manual fix: Add <th scope="col"> for column headers and <th scope="row"> for row headers:
<table>
<thead>
<tr>
<th scope="col">Size</th>
<th scope="col">Chest (in)</th>
<th scope="col">Waist (in)</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">S</th>
<td>34-36</td>
<td>28-30</td>
</tr>
</tbody>
</table>
AccessComply auto-fix: Yes. The TableAgent detects tables without proper header structure and adds the appropriate semantic markup.
Automating vs. Manual Fixes
Of the 10 violations above, 8 are fully auto-fixable by AccessComply. The two that require manual attention (complex form flow testing and custom interactive widgets) need developer review.
AccessComply's scan will identify which specific violations exist in your store, where in your theme files they occur, and which agent will fix each one. The typical Shopify store has 20-80 total violations across these categories, with about 70-80% addressable by automated fixes.
Further Reading
Ready to Fix Your Store?
Scan your Shopify store for free. Automatically fix 70–80% of WCAG 2.1 AA violations with real source-code changes — no overlay widgets.