WooCommerce accessibility: common issues and how to fix them
WooCommerce runs on roughly 28% of all ecommerce sites, making it the most widely deployed ecommerce platform by far. That scale also makes it one of the most common sources of ADA accessibility complaints. Unlike Shopify, WooCommerce gives developers deep control over markup and behavior. That control is a double-edged sword: it means more can go wrong, but it also means most problems can be fixed without waiting for a platform update.
This guide covers accessibility failures that are specific to WooCommerce: the Storefront theme, WooCommerce Blocks, the classic shortcode checkout, variable products, the mini-cart widget and common plugin conflicts. Not WCAG theory in the abstract, but the actual markup and behavior problems that appear in real WooCommerce audits. For the complete criteria reference, see our WCAG 2.1 AA ecommerce checklist.
What makes WooCommerce accessibility different from generic WordPress accessibility
WordPress core has steadily improved its accessibility. The Gutenberg block editor now produces reasonable semantic HTML for static content. But WooCommerce introduces its own JavaScript-heavy components on top of WordPress: the cart, checkout, product gallery, variable product forms and mini-cart widget all have their own accessibility surface area that is separate from anything in WordPress core.
The situation becomes more complex because WooCommerce offers two distinct approaches to its storefront: the classic shortcode-based templates and the newer WooCommerce Blocks. Both are in active use. The Blocks approach (used in the new Cart Block and Checkout Block) behaves very differently from the classic shortcode templates and has its own accessibility profile.
Storefront theme accessibility: what the default configuration gets wrong
The Storefront theme is WooCommerce's official free theme. It is a reasonable starting point but several default behaviors cause WCAG failures.
Skip navigation link
Storefront includes a skip link ("Skip to content") as the first focusable element. This is correct. However, many WooCommerce sites using Storefront as a parent theme with a child theme override or accidentally hide this link. Check that your skip link is visible on focus. The CSS rule outline: none applied globally will hide the focus indicator on the skip link. The rule display: none will remove it from the tab order entirely.
Product loop grid
On collection pages, each product in the grid is typically a <li> element containing an image, a title link, a price and an add-to-cart button. The default Storefront template renders both the product image and the product title as separate links pointing to the same product URL. This creates duplicate link text: two consecutive focusable elements that both say "View product" or the product name, depending on configuration.
The fix: combine the image and title into a single link, or mark the image link as aria-hidden="true" and tabindex="-1" so only the text link receives keyboard focus. The WooCommerce template file to edit is woocommerce/templates/content-product.php, overridden in your theme's woocommerce/ folder.
Add to cart button accessibility names
On archive/collection pages, the add-to-cart button default text is "Add to cart" for simple products. This is insufficient context when multiple products appear on the page. A screen reader user navigating by buttons hears a list of identical "Add to cart" labels with no product name context.
Fix this with a filter in your theme's functions.php:
add_filter('woocommerce_loop_add_to_cart_args', function($args, $product) { $args['aria-label'] = sprintf('Add %s to cart', $product->get_name()); return $args; }, 10, 2);
Variable product selectors and WCAG compliance
Variable products (products with size, color or material variants) are the most common source of serious accessibility failures on WooCommerce stores. Many of these failures relate to form accessibility fundamentals like label association and state communication. The default implementation has several problems.
Native select elements vs custom swatches
WooCommerce's default variable product form uses native <select> elements for each attribute. Native selects are keyboard accessible and announced correctly by screen readers. They are not glamorous, but they work.
The problem arrives when merchants install swatch plugins (Variation Swatches for WooCommerce, GP Premium swatches, YITH WooCommerce Swatches) that replace native selects with custom button groups or image-based selectors. These custom implementations frequently fail WCAG:
- Missing accessible names on swatch buttons. A color swatch button showing a blue circle must have an accessible name ("Blue") and ideally context ("Color: Blue").
- No selected state communicated. When a user selects a variant, the visual state changes (bold border, checkmark) but no
aria-pressed="true"oraria-checked="true"is set. Screen reader users do not know which variant is currently selected. - Unavailable variants not communicated. Out-of-stock variants shown with a strikethrough need
aria-disabled="true"and ideally a tooltip or label fragment like "(Out of stock)". - No
<fieldset>grouping. WCAG requires that related form controls have a group label. A set of size buttons ("XS", "S", "M", "L", "XL") needs a<fieldset>with a<legend>saying "Size" so screen reader users understand what they are choosing.
Price update announcements
When a user selects a variant, WooCommerce updates the price display via JavaScript. This updated price is not announced to screen reader users because the price element does not have an ARIA live region. Add aria-live="polite" and aria-atomic="true" to the price element in your variable product template:
<span class="price" aria-live="polite" aria-atomic="true">
This ensures that when JavaScript updates the price content, the screen reader will announce the new price automatically.
WooCommerce product gallery accessibility
The default product gallery uses Flexslider or a lightbox-based gallery depending on the theme. Both have accessibility problems in their default configuration.
Gallery thumbnail buttons
Thumbnail images that switch the main product image when clicked are typically rendered as <a> elements or <div> elements. The <div> approach is particularly problematic: it is not keyboard focusable by default and has no role, making it completely inaccessible to keyboard users and screen readers.
Fix: ensure thumbnail controls are <button> elements (or use role="button" and tabindex="0" if you cannot change the element). Each thumbnail button needs an accessible name: aria-label="View image 2 of 5: Blue t-shirt worn outdoors".
Lightbox focus trapping
When users click to view a full-size product image in a lightbox, the lightbox must trap focus. Without a focus trap, keyboard users can Tab behind the lightbox overlay and interact with the page beneath it. The lightbox overlay must use role="dialog", aria-modal="true" and an aria-label. Focus must move into the dialog on open and return to the triggering thumbnail on close.
PhotoSwipe (used by many WooCommerce gallery plugins) has improved its accessibility in version 5. If you are running PhotoSwipe v4 or earlier, upgrade. Version 5 includes proper focus trapping, ESC key dismissal and ARIA roles.
AJAX cart updates and screen reader announcements
When a user adds a product to the cart on a WooCommerce store, several things typically happen: a success message appears, the mini-cart widget updates its count and the page may show a toast notification. None of this is announced to screen reader users by default.
What WCAG requires
WCAG 4.1.3 (Status Messages, Level AA) requires that status messages be programmatically determinable without receiving focus. When your AJAX cart update succeeds, that success message is a status message. It must be announced via a live region, not by moving focus.
The fix
Add a visually hidden live region to your theme's HTML structure:
<div id="wc-cart-status" aria-live="assertive" aria-atomic="true" class="sr-only"></div>
Then in your JavaScript, update this element when a cart action completes:
document.querySelector('#wc-cart-status').textContent = productName + ' added to cart. Cart now contains ' + itemCount + ' items.';
WooCommerce fires a JavaScript event added_to_cart on the document when an AJAX add-to-cart completes. Hook into this event to trigger the live region update. The wc_cart_fragments_refreshed event fires when the mini-cart widget has updated, which is the right point to announce the updated count.
Mini-cart widget accessibility
The WooCommerce mini-cart widget (added to a theme sidebar or header via widgets) has its own set of issues.
- Cart icon buttons. The cart icon in a header (typically an SVG icon) often has no accessible name. Use
aria-label="Cart (3 items)"on the link or button element. The item count in the accessible name updates via JavaScript should also update thearia-label. - Mini-cart dropdown panel. If the mini-cart uses a dropdown panel that appears on hover or click, it must be keyboard accessible. The panel should be a
role="dialog"if it traps focus, or arole="region"with anaria-labelif it does not. Triggering it via hover only (no keyboard trigger) violates WCAG 2.1.1. - Remove item buttons. "Remove" links next to cart items need context:
aria-label="Remove Blue t-shirt from cart". Plain "Remove" or "X" labels are ambiguous when multiple items are in the cart.
WooCommerce Blocks checkout accessibility
The WooCommerce Cart Block and Checkout Block (introduced as the default in WooCommerce 8.3 in late 2023) are built with React and have a different accessibility profile from the classic shortcode templates.
What the Checkout Block does well
WooCommerce's development team has done accessibility work on the Blocks. Form inputs in the Checkout Block have properly associated labels. Error messages are linked to their fields using aria-describedby. The block structure uses appropriate heading levels for each step section.
Known Checkout Block failures
In testing across multiple WooCommerce 8.x and 9.x stores in 2025 and 2026, consistent issues appear:
- Focus management between steps. After completing the "Contact" section and tabbing to the "Shipping" section, focus placement is inconsistent across browsers. In Firefox with NVDA, focus sometimes drops to the document body rather than the next section heading.
- Express payment buttons. PayPal, Apple Pay and Google Pay express checkout buttons injected by the payment plugin often lack accessible names or have names that are icon-only ("PayPal" text inside an SVG with no alt text).
- Coupon code accordion. The toggle that expands the coupon code input uses a button but the expanded state is communicated only via CSS class changes, not via
aria-expanded. - Order notes textarea. The "Additional information" order notes field, when added via a block extension, sometimes renders without a programmatically associated label.
Common plugin conflicts that break accessibility
WooCommerce plugins often conflict with each other in ways that create accessibility regressions. The most common patterns:
- Page builder plugins. Elementor, Divi and WPBakery add wrapper elements around WooCommerce templates that can break heading hierarchy (inserting extra heading levels) and remove semantic structure (replacing semantic elements with generic divs).
- AJAX filter plugins. WooCommerce Product Filters, FacetWP and YITH WooCommerce AJAX Product Filter replace the standard WooCommerce archive page loop with AJAX-loaded content. When filter selections update the product grid, the update must be announced via a live region and focus must be managed appropriately.
- Product quick-view plugins. Quick-view modals injected by plugins (YITH Quick View, WooCommerce Product Table) regularly fail to implement proper modal focus trapping and do not return focus to the triggering button on close.
- Wishlist plugins. YITH WooCommerce Wishlist adds "Add to Wishlist" buttons with icon-only accessible names. The heart icon SVG has no accessible name and the button has no aria-label.
Testing WooCommerce accessibility with screen readers
Automated testing with axe-core catches a portion of WooCommerce accessibility failures: roughly 30-40% of total issues, consistent with the industry average. See our accessibility testing tools comparison for details on tool coverage. The remaining failures require keyboard and screen reader testing.
For WooCommerce specifically, the flows that need manual screen reader testing are:
- Variable product selection. Can you select a size and color variant using only the keyboard? Does the screen reader announce which variant is selected?
- Add to cart. Does the screen reader announce that the product was added? Does the cart count update announcement happen without needing to navigate to the cart?
- Cart editing. Can you change quantities and remove items using only the keyboard? Does the screen reader announce the updated totals?
- Checkout form completion. Can you complete all form fields, select a shipping method, enter payment details and submit the order without using a mouse?
Use NVDA with Firefox on Windows (the most common screen reader and browser combination per WebAIM surveys) and VoiceOver with Safari on macOS. Test the same flows on both. Failures that appear on one combination but not the other are still failures.
Priority order for WooCommerce accessibility fixes
Not all issues carry equal legal and commercial risk. Prioritize in this order:
- Checkout form labels and error messages. Missing labels on payment and address fields directly prevent purchase completion and are the most likely targets in ADA complaints. See our accessible forms guide for implementation details.
- Variable product selection. If users cannot select a variant using a keyboard, they cannot add the product to the cart. This is a WCAG 2.1.1 failure (keyboard) and a direct revenue impact.
- Cart AJAX announcements. WCAG 4.1.3 status message failures are increasingly cited in demand letters.
- Color contrast. WooCommerce's default sale badge, price styling and button colors frequently fail WCAG 1.4.3.
- Product loop duplicate links. Lower severity but affects many pages and is quick to fix.
Frequently asked questions
- Is WooCommerce accessible out of the box?
- WooCommerce inherits accessibility from its WordPress theme. The Storefront theme includes basic accessibility support, but most third-party themes have significant gaps. WooCommerce core checkout has known accessibility issues with payment gateway integrations.
- Do WooCommerce plugins affect accessibility?
- Yes. Plugins that modify checkout, add popups or inject widgets frequently introduce accessibility violations. WordPress accessibility plugins can help with some issues, but plugin-based fixes are fragile and may break with updates.
- How does WooCommerce compare to Shopify for accessibility?
- Shopify's native checkout is generally more accessible than WooCommerce's default checkout. WooCommerce offers more customization flexibility, which can be used to improve accessibility but also introduces more opportunities for violations.
Complyko scans WooCommerce stores across all key purchase flows: product pages, cart and checkout. For comparison, see our guides on Shopify and BigCommerce accessibility. Get a free report showing which violations carry the highest legal risk on your specific store.
Get your free scan →