I build a WordPress accessibility scanner. Last week a marketplace reviewer
rejected it, and among the reasons was this:
The compliance rules need correction. "Language of parts" only validates
existing lang attributes and cannot detect unmarked foreign-language passages;
the main-landmark rule is WCAG 1.3.6 Level AAA but is marketed as an AA check;
and duplicate IDs should not be presented as a WCAG 2.2 failure under 4.1.1.
Three findings. All three correct. What follows is what happened when I stopped
fixing the three and checked the other twenty-two.
The rule that no longer exists
Start with the third one, because it is the easiest to verify and the most
widely wrong.
Success criterion 4.1.1 Parsing was removed from WCAG 2.2. Not deprecated,
not softened — removed. The W3C Recommendation lists it in the
conformance section as "Parsing (Obsolete and removed)". It went because the
thing it protected against — assistive technology choking on malformed markup —
stopped being a real failure mode once browsers and accessibility APIs
converged on how to recover from bad HTML.
My scanner reported duplicate id attributes as a WCAG 4.1.1 failure. Against
WCAG 2.2, that criterion is not there to fail.
Duplicate ids are still worth fixing. They break label for pairings and
aria-labelledby references, so the wrong element gets announced, or none does.
But that is a 4.1.2 problem when it actually breaks an accessible name, and
detecting that is a different check from counting duplicate ids. What I had was
a generic duplicate-id check wearing a criterion number that had been retired.
Then I checked the rest
The reviewer had found three. I could have fixed three. Instead I took all 25
rules and checked each one against the WCAG 2.2 Recommendation and against how
axe-core classifies the equivalent rule — because axe-core is the
reference implementation most of this industry is built on, and it makes a
distinction I had lost.
Eight rules were wrong.
| Rule | Claimed | Actually |
|---|---|---|
| Duplicate ids | 4.1.1 | Removed from WCAG 2.2 |
| One main landmark | 1.3.6 AAA | 1.3.6 is Identify Purpose, an unrelated criterion |
| Language of parts | 3.1.2 AA | 3.1.2 is level A — and the check does not do what its title claimed |
| Vague link text | 2.4.4 | 2.4.4 is satisfiable from surrounding context |
| Skipped heading levels | 1.3.1 | WCAG does not require sequential heading levels |
Missing h1
|
1.3.1 | Recommended practice |
| Empty heading | 1.3.1 | Recommended practice |
Positive tabindex
|
2.4.3 | Recommended practice |
Some of those deserve a sentence.
Vague link text. 2.4.4 is Link Purpose (In Context). In context. A link
that says "read more" satisfies it if the surrounding paragraph, list item or
table cell makes the destination clear — which is usually the case. The
criterion that demands the link text stand alone is 2.4.9, and it is AAA. So
"read more" repeated down a page is a real usability problem for someone
tabbing through links, and it is not a level A failure.
Heading levels. There is no success criterion requiring h2 to follow h1.
1.3.1 Info and Relationships requires that structure conveyed visually is
available programmatically — using headings at all is how you satisfy it.
Skipping from h1 to h3 is untidy and it makes screen reader navigation worse,
but it is not what 1.3.1 says. axe-core classifies heading-order as best
practice, and has for years.
Language of parts. This one was wrong twice. 3.1.2 is level A, not AA — I
had the level wrong. And the check was titled "Foreign-language passages should
declare their language", which promised something no automated check can do: to
know that a passage is in another language when nothing marks it as such. What
the code actually did was validate lang attributes that were already present.
That is a useful check. It is not the check the title advertised.
So what are the real numbers
25 checks. Eighteen map to a WCAG 2.2 success criterion, across fourteen
distinct criteria at levels A and AA: 1.1.1, 1.3.1, 1.3.5, 1.4.2, 1.4.3, 1.4.4,
2.4.1, 2.4.2, 2.4.4, 2.5.8, 3.1.1, 3.1.2, 3.3.2 and 4.1.2.
Seven are recommended practice. Worth fixing, not conformance failures.
Before the audit, the product page said "25 automated checks across WCAG 2.2
levels A and AA" and listed 4.1.1 among the criteria covered. Both of those were
false, and the second was checkably false by anyone who had read the 2.2
Recommendation.
Why this is not pedantry
Here is the part that made me stop treating it as a labelling problem.
The plugin has a generator for the accessibility information the European
Accessibility Act requires. It prefills the "known barriers" section from your
most recent scan, and — this was the selling point — it attaches the WCAG
success criterion to each barrier.
So eight rules citing criteria that were wrong, obsolete, or unrelated were
writing those numbers into a document the site owner publishes as a legal
declaration about their own service.
A conformance claim is not a report. A report that overstates gives you a worse
afternoon. A published statement that cites a criterion that does not exist, on
a document you are legally obliged to maintain, is a different category of
mistake, and it is one your customer discovers rather than you.
That is the argument for the distinction, and it is the only one that matters. A
tool that presents every finding as a WCAG failure inflates two numbers: its own
— 25 WCAG checks reads better than 18 — and yours. And your inflated number
is the one that ends up in public.
What I changed
Every rule now declares what it is:
{
id: 'heading_order',
wcag: '',
level: '',
standard: 'best-practice',
...
}
The report prints the criterion where there is one, and Best practice where
there is not, instead of an empty WCAG ().
The statement generator now requires two independent conditions before it
will print a criterion into a legal document: the rule must be marked as
WCAG-mapped, and its value must match ^\d+\.\d+\.\d+$. Either one alone
would have been enough to stop what happened. I wanted the one that survives
someone editing the other.
And the marketing copy now says 18 and 7, in the readme, the documentation and
the marketplace listing. That was the least pleasant commit of the week and the
one I would repeat.
If you build or buy one of these tools
Three questions worth asking, none of which require you to trust me.
Does it still report 4.1.1? Thirty seconds to check, and it tells you when
the rule set was last read against the standard rather than copied from another
tool.
Does it distinguish success criteria from good practice? If every finding
carries a criterion number, at least some of those numbers are decoration. The
reference implementation this industry runs on marks roughly a quarter of its
rules as best practice. A tool with none is not stricter; it is less careful.
Where does the criterion go after the report? If it flows into a statement,
a badge, a PDF, or anything a customer publishes, the accuracy stops being an
internal quality matter.
The part that has not changed
Automated testing finds roughly a third of real accessibility barriers. Getting
the labels right does not move that number. A clean report is a good sign, not a
conformance statement, and keyboard and screen reader testing by a person is
still the only way to know.
What the audit changed is narrower and, I think, worth the week: when my tool
now says WCAG, it means it.
About this
This was written by the person who builds the plugin it discusses. That is
stated plainly rather than buried, so you can weigh it.
Accessibility Audit — WCAG & EAA Compliance Checker
Originally published on groundedwp.com.
Top comments (0)