A WooCommerce Accessibility Audit of My Own Theme: Three WCAG 2.1 AA Failures, All in the CSS
Last week I ran a WooCommerce accessibility audit against WCAG 2.1 AA — not on a client store, but on Aviendha, the block theme I build stores on and put my own name to. I expected it to come back clean. It came back with three failures. All three were contrast or focus problems, all three lived entirely in CSS, and all three had been shipping for months without anyone noticing.
This post walks through exactly what failed, the measured numbers behind each failure, and why these particular mistakes are so easy to ship. If you run a WooCommerce store in the EU, the same three failure classes are the ones most likely to be sitting in your theme right now — they’re invisible in a design review and invisible to most automated scanners. Last updated: July 27, 2026.
Quick Summary: A WCAG 2.1 AA audit of my own WooCommerce block theme surfaced three failures. One: the border color used on form controls measured 1.25:1 against the page background, where WCAG 1.4.11 requires 3:1 — the unchecked filter checkbox had a boundary nobody could see. Two: a muted text color measured 4.49:1 against a 4.5:1 requirement, missing 1.4.3 by one hundredth, on post meta, placeholder text, and the struck-through sale price. Three: two form controls removed the focus outline and swapped a 1px border color instead — technically a visible indicator under 2.4.7, practically imperceptible. The pattern behind all three: each was a deliberate design decision that was never measured. Contrast and focus failures don’t look like bugs, which is exactly why they ship.
In This Guide
- Why I Audited a Theme I Wrote Myself
- Failure One: A Border Nobody Could See
- Failure Two: Missing 4.5:1 by One Hundredth
- Failure Three: Focus Rings That Repainted the Same Pixel
- What This Means for Your Store
- What Aviendha Actually Is — and What It Doesn’t Do
- How to Run the Same Audit on Your Store
- Frequently Asked Questions
Why I Audited a Theme I Wrote Myself
The European Accessibility Act has been in force since June 28, 2025. It doesn’t spell out technical requirements itself — it points at the harmonized standard EN 301 549, which in turn points at WCAG 2.1 level AA. So for anything on the web, EAA compliance means WCAG 2.1 AA compliance. I’ve written about whether the EAA actually applies to your WooCommerce store, including the micro-enterprise exemption that covers a lot of smaller shops.
Writing that post is what prompted this one. It felt dishonest to explain the standard to store owners without holding my own work to it. So I audited Aviendha — the lean full-site-editing theme I build WooCommerce stores on — against WCAG 2.1 AA, control by control.
Three failures came back. Nothing structural: the heading hierarchy was sound, the templates used real landmarks, form fields had proper labels, and the markup didn’t move an inch during the fix. Every failure was a color or an outline. That’s the part worth paying attention to, because it means a theme can look completely finished, pass a casual review, and still fail the standard.
Failure One: A Border Nobody Could See
WCAG 1.4.11 (Non-text Contrast) requires at least 3:1 between a user interface component’s visual boundary and the background behind it. The theme had a palette color called border-light at #E5DED2, used for card edges, hairline rules, and — this was the mistake — form control borders.
Measured against the page background #FAF7F2, border-light comes out at 1.25:1. Against a 3:1 requirement, that isn’t a near miss. It means every form control the theme styled had a boundary that was, for practical purposes, not there.
The shop filter checkbox was the sharp case. The theme’s WooCommerce stylesheet removes WooCommerce’s default currentColor wash from the unchecked box and lets the border define the control instead — a cleaner look, and the same filter sidebar I described in building the shop filter drawer on a block theme. But once the wash is gone, that invisible hairline is the entire unchecked state. A shopper filtering by size or price had no reliable way to see which boxes were off.
| Token | Value | On page background | 1.4.11 requires | Result |
|---|---|---|---|---|
border-light (before) | #E5DED2 | 1.25:1 | 3:1 | Fail |
control-border (after) | #8C8378 | 3.49:1 | 3:1 | Pass |
control-border on tinted panels | #8C8378 | 3.09:1 | 3:1 | Pass |
The fix was a new token rather than a change to the existing one. border-light is still correct for decorative rules, card edges, and group separators — 1.4.11 simply doesn’t reach those, and changing it would have darkened every hairline in the design for no accessibility gain. So control-border was added specifically for control boundaries, at #8C8378.
Check the tighter background, not the friendlier one. A token has to clear the threshold against every surface it lands on. control-border measures 3.49:1 on the page background but only 3.09:1 on the theme’s tinted panels — still passing, but with far less headroom. If you test a color against your lightest background and call it done, you haven’t tested it.
Failure Two: Missing 4.5:1 by One Hundredth
WCAG 1.4.3 (Contrast Minimum) requires 4.5:1 for normal-size text. The theme’s muted text color, main-accent, was #78716C — a perfectly ordinary warm gray that measures 4.49:1 against the page background.
One hundredth of a point. There is no visual difference between 4.49:1 and 4.5:1 that any human can perceive, and no design review would ever catch it. But the threshold is a threshold, and a conformance check reports it as a failure. This is the single most instructive finding of the audit: you cannot eyeball this.
The color wasn’t in some obscure corner either. It was carrying:
- Comment form labels and placeholder text
- Post meta, the author byline, and comment dates
- Sidebar widget titles and eyebrow labels
- The struck-through original price on sale items — on a store, the one number a shopper is comparing against
The replacement, #6F6862, measures 5.13:1 on the page background and 4.54:1 on the tinted panels. Note which one is tighter: the panels, again. That’s the surface any future adjustment has to be checked against, not the page background that looks more forgiving.
Failure Three: Focus Rings That Repainted the Same Pixel
WCAG 2.4.7 (Focus Visible) requires a visible indicator on the focused element. Two controls in the theme — the comment form fields and the WooCommerce catalog sorting dropdown — removed the browser’s default outline and changed a 1px border color in its place.
Technically, that is a visible indicator. Practically, it repaints the exact same pixel the resting state already draws. And because that border sat at the 1.25:1 from failure one, the change was close to imperceptible. A keyboard user tabbing through the sort dropdown got no usable signal about where they were.
Both now use a real ring — outline: 2px solid in the theme’s primary color at a 2px offset — which matches the quantity stepper, the one control in the theme that already had focus handling right. The comment form also moved from :focus to :focus-visible at the same time, so clicking into a field with a mouse no longer rings it while keyboard tabbing still does.
The border-swap focus pattern is everywhere. Replacing outline with a border color change is one of the most common CSS idioms in commercial themes, because a default outline is considered ugly. It is also one of the most common ways to fail 2.4.7. If you inherited a theme from anyone, search its stylesheets for outline: none and outline: 0 and check what replaced them.
What This Means for Your Store
Three failures, one shared cause: each was a deliberate design decision that nobody measured. Not sloppiness, not missing markup — considered choices about how a control should look, made without checking the number.
That matters for your store because it means the usual signals don’t help you. A theme that looks polished tells you nothing. A vendor’s “accessibility ready” tag tells you nothing about the specific colors you picked in the customizer. And most automated scanners will not catch the checkbox case at all, because they check text contrast far more reliably than they check control boundaries.
| Failure class | Where it hides in a WooCommerce store | Caught by automated scan? |
|---|---|---|
| Control boundary contrast (1.4.11) | Filter checkboxes, quantity steppers, variation dropdowns, form field borders | Often missed |
| Text contrast (1.4.3) | Sale price strikethrough, stock status, tax notes, placeholder text, product meta | Usually caught |
| Focus visibility (2.4.7) | Sort dropdown, checkout fields, filter controls, quantity inputs | Rarely caught |
Note where those land: the sort dropdown, the filter sidebar, the variation picker, the checkout fields. That’s the purchase path. Accessibility failures and conversion problems tend to occupy the same real estate, which is why the fixes usually pay for themselves regardless of whether the EAA applies to you — a point I get into in WooCommerce conversion rate optimization for EU stores.
What Aviendha Actually Is — and What It Doesn’t Do
Since this post is built on it, here’s an honest scope. Aviendha is a lean full-site-editing theme for WooCommerce stores, GPL-3.0, requiring WordPress 6.6+ and PHP 8.0+. You can see it running on the live demo store.
What it does
- Ships no JavaScript at all. No build step, no bundler. The scroll-driven header edge and the reading-progress bar use CSS
animation-timeline: scroll()rather than scroll listeners; where it’s unsupported, the effect simply doesn’t appear. - Self-hosts its fonts. Bricolage Grotesque and JetBrains Mono are bundled as local WOFF2 files, so no visitor IP is sent to a third-party font CDN — a real consideration in Germany in particular.
- Ships store templates for the product archive, single product, product search results, order confirmation, and coming-soon pages, plus per-product-type add-to-cart layouts.
- Ships no patterns. It removes core’s block patterns and unregisters WooCommerce’s bundled ones, because pages are composed directly from blocks. Content blocks come from the companion Aludra library, which is recommended but not required.
- Degrades without WooCommerce. With the plugin inactive, store templates are filtered out and the header’s mini cart is stripped, rather than left rendering as unsupported-block placeholders.
What it doesn’t do
This is the part that usually gets oversold, so let me be direct. A theme is a presentation layer. Aviendha does not handle EU VAT, OSS thresholds, or VAT ID validation — that’s WooCommerce core plus a tax plugin, and I’ve covered the setup in the WooCommerce EU VAT guide. It does not provide cookie consent; that’s a plugin’s job, and I maintain Warder for it. It does not add payment methods — see iDEAL, Bancontact and Klarna for EU stores for that. And it does not make your store WCAG-compliant on its own: a theme can only get its own markup and CSS right. Your product images still need alt text, and your own content still has to clear the same thresholds.
It’s a sibling to Elayne, which does ship patterns — see the Elayne v4 release notes — and to Nynaeve, which registers its own blocks. Different tradeoffs for different projects.
How to Run the Same Audit on Your Store
You don’t need a specialist for the first pass. This is the sequence I used, and it will find the same three failure classes on most stores in under an hour.
- List your theme’s colors, then measure every pair. Pull the palette out of
theme.jsonor your customizer settings and run each text color against each background it actually lands on. Text needs 4.5:1; control borders need 3:1. Check the tightest background, not the lightest. - Grep your stylesheets for
outline: noneandoutline: 0. For each hit, tab to that control in a browser and confirm you can see where you are. If the only change is a 1px border color, it fails in practice. - Tab through the purchase path with the mouse untouched. Shop archive, filter sidebar, sort dropdown, product page, variation picker, quantity stepper, cart, checkout. You should always know where focus is. This one test finds more than any scanner.
- Check the unchecked states specifically. Filter checkboxes, radio buttons, and empty form fields are where boundary contrast fails, because the “off” state is often nothing but a border.
- Run an automated scan last, not first. It will catch text contrast reliably and miss most of the rest. Treat a clean report as the floor, not the finish line.
If you’d rather start with a broader picture of your store’s technical health, the free WooCommerce Checkup covers speed and configuration alongside the basics, and the full store audit checklist walks through the rest.
Frequently Asked Questions
- What is a WooCommerce accessibility audit? It’s a review of your store against WCAG 2.1 level AA, the standard the European Accessibility Act points to through EN 301 549. In practice it covers color contrast for text and controls, keyboard navigation through the entire purchase path, visible focus indicators, form field labeling, and image alt text. The purchase path matters most: shop archive, filters, product page, cart, and checkout.
- What contrast ratio does WCAG 2.1 AA require? Normal-size text needs 4.5:1 against its background, and large text needs 3:1. User interface components and graphical objects — form control borders, icons, focus indicators — need 3:1 under 1.4.11. These are hard thresholds: 4.49:1 fails where 4.5:1 passes, even though no one can see the difference.
- Can an automated scanner find all accessibility problems? No. Automated tools reliably catch text contrast failures and missing alt attributes, but they routinely miss control boundary contrast and focus visibility problems. In this audit, the two failures involving controls would likely not have been reported by a scan alone. Manual keyboard testing found them.
- Is it a WCAG failure to remove the browser’s default focus outline? Only if you don’t replace it with something visible. Removing the outline and changing a 1px border color instead is technically an indicator, but if that border has low contrast against the resting state, the change is imperceptible and fails 2.4.7 in practice. A 2px outline in an accent color at a small offset is the reliable fix.
- Does the European Accessibility Act apply to my WooCommerce store? It applies to online shops selling to EU consumers, but micro-enterprises providing services — fewer than 10 employees and under €2 million annual turnover — are exempt. You must meet both conditions to qualify for the exemption. If you’re above either threshold, the EAA applies and WCAG 2.1 AA is the standard you’re measured against.
- Does using an accessible theme make my store compliant? No. A theme can only get its own markup and CSS right. Your product images still need alt text, your own written content still has to meet contrast thresholds, and any plugin that renders on the front end — page builders, popups, review widgets — brings its own markup that the theme doesn’t control. An accessible theme removes a large class of problems, but it’s a starting point.
- What is Aviendha? Aviendha is a lean full-site-editing WordPress theme for WooCommerce stores, licensed GPL-3.0 and maintained by Imagewize. It ships a design system through theme.json, WooCommerce block templates, and style variations, but no theme-level patterns — pages are composed directly from blocks. It requires WordPress 6.6+ and PHP 8.0+, and ships no JavaScript.
- Where can I see or download Aviendha? There’s a live demo store at demo.imagewize.com/aviendha, and the source is on GitHub at github.com/imagewize/aviendha. It is not currently listed in the WordPress.org theme directory.
- Does Aviendha handle EU VAT, cookie consent, or payment methods? No. A theme is a presentation layer. EU VAT and OSS handling come from WooCommerce core plus a tax plugin, cookie consent comes from a consent plugin, and payment methods come from gateway plugins. Aviendha styles what those produce; it doesn’t replace them.
- How long does a first-pass accessibility audit take? For a typical WooCommerce store, measuring your palette and tabbing through the purchase path takes about an hour and will surface the most common failures. A full conformance audit covering every WCAG 2.1 AA success criterion across all templates is considerably more involved, but the first pass finds the issues that affect the most shoppers.
Want Your WooCommerce Store Audited Properly?
I audit and fix WooCommerce stores against WCAG 2.1 AA — the standard the European Accessibility Act measures you against. Hourly at €65, or a fixed-price quote for the full pass.
- Palette measured against every surface it lands on, text and controls
- Keyboard walkthrough of the full purchase path, archive to checkout
- Focus indicators, form labeling, and heading structure across templates
- A written report with the measured numbers and the specific CSS to change