WCAG 2.2 without myths: why a Lighthouse score of 100 does not mean an accessible website

Two men are looking at the same admin panel. Next to every order there is a dot: green means paid, red means a payment problem. Both have the same word in their medical records: colour blindness. The first one sees the difference easily, although the colours look a little muted to him. The second one sees two very similar brownish dots.

There is no contradiction here. "Colour blindness" is a label for a whole family of conditions of varying severity. The first man has mild deuteranomaly, the second has deuteranopia. A website that "works for colour-blind people" because someone checked it once in a simulator may work for only one of them.

This example explains well how the WCAG guidelines are built and why they are so hard to simply "tick off". The argument of this article is simple:

A green result in a tool does not mean an accessible website. WCAG 2.2 describes an outcome, not a specific user — because people with "the same" disability have different needs. That is why conformance is checked by a human, and maintained in shared components, not page by page.

Automated tools are necessary. But they are the first sieve, not the verdict. I will show this with an example: today goatcms.com passes an axe test without a single violation, although before the latest round of fixes it had dozens of problems, most of which an automated tool would not have noticed — and it still has a few.

This text is long because the topic is broad. Feel free to read it selectively.

Table of contents

  1. What WCAG 2.2 is and who is behind it
  2. Four principles: POUR
  3. Levels A, AA and AAA
  4. Same diagnosis, different needs
  5. What changed in WCAG 2.2 compared with 2.1
  6. Criteria in practice: how to check them during an audit
  7. How to check conformance
  8. Getting to AAA — and whether to try at all
  9. Case study: goatcms.com and the standard GOAT module
  10. Where this argument may be wrong
  11. 15 minutes before publishing: a cheat sheet
  12. Sources

What WCAG 2.2 is and who is behind it

WCAG (Web Content Accessibility Guidelines) are the guidelines for making web content accessible. They are published by the W3C — the organisation that standardises HTML and CSS, among other things — and more precisely by its WAI (Web Accessibility Initiative).

Key dates:

  • WCAG 2.0 — December 2008,
  • WCAG 2.1 — June 2018,
  • WCAG 2.2 — 5 October 2023, with a corrected text dated 12 December 2024.

In 2025 WCAG 2.2 also became the standard ISO/IEC 40500:2025. Its content is identical to the W3C version from October 2023 (W3C: WCAG 2 Overview). This matters for public procurement and for regulations that prefer to reference ISO standards rather than documents of industry organisations.

WCAG 2.2 consists of 4 principles, 13 guidelines and 86 success criteria. The W3C does not state the last number directly — it follows from the table of contents: 87 numbers minus one criterion removed in version 2.2.

Briefly, because this is an article about practice, not a legal guide:

  • Public bodies (government offices, schools, hospitals) have been subject to the Polish Act on Digital Accessibility since 2019. Its annex corresponds in practice to WCAG 2.1 at level AA. They must also publish an accessibility statement (gov.pl).
  • Private companies have been covered since 28 June 2025 by the Act of 26 April 2024, the Polish implementation of the European Accessibility Act (EAA). It applies, among others, to online shops, banking and e-books. Micro-enterprises providing services are exempt. Supervision is exercised, among others, by the President of the Management Board of PFRON (the State Fund for Rehabilitation of Disabled Persons). A fine may reach ten times the average monthly salary, but no more than 10% of turnover (text of the act, art. 73).
  • The EN 301 549 standard, through which the EAA in practice "reaches for" WCAG, moves from WCAG 2.1 to WCAG 2.2 A and AA in version 4.1.1 (published in September 2026). It will gain legal effect after publication in the Official Journal of the EU, expected at the end of 2026 (Deque).

The practical conclusion: if you are designing or rebuilding a website today, aim for WCAG 2.2 AA. That is what the W3C recommends, even where formal obligations still point to an older version. And content that conforms to 2.2 automatically conforms to 2.1 and 2.0.

One note on naming: the W3C translations page lists the available translations of each WCAG version (W3C translations list). In this article I use the official English names of the criteria.

A starter glossary

These terms will come back later in the text.

  • Success criterion — a specific, testable requirement, e.g. "1.4.3 Contrast (Minimum)". The number tells you which principle and guideline it belongs to.
  • Conformance level — A, AA or AAA. Each criterion is assigned one level.
  • Technique — a proven way of meeting a criterion. "Sufficient" techniques meet the criterion, "advisory" ones improve accessibility beyond the minimum.
  • Failure — a way, documented by the W3C, of *not* meeting a criterion, e.g. F65: an image without an alt attribute.
  • Understanding — W3C documents explaining each criterion: its intent, who it helps, examples. The best place to go when a criterion sounds unclear.
  • Assistive technology — software or hardware that helps people use a computer: a screen reader, a magnifier, voice control, a switch, a braille display.
  • Screen reader — a program that turns what is on the screen into speech or braille. The most popular ones: JAWS, NVDA, VoiceOver, TalkBack.
  • Accessible name — what a screen reader announces as the name of an element, e.g. "Log in, button". It comes from the text, a label, the alt attribute or ARIA.
  • ARIA — HTML attributes (aria-label, aria-expanded, role etc.) that pass to assistive technologies information that cannot be expressed in HTML alone. The practitioners' rule: native HTML first, ARIA only when HTML is not enough.
  • Landmark — a region of a page with a defined role (header, navigation, main content, footer) that a screen reader user can jump between.
  • Focus — the indication of which element will receive the next keyboard command. It is usually visible as an outline.
  • Conformance claim — a statement that a website meets WCAG at a given level. WCAG does not require it; Polish law does for the public sector (as an accessibility statement).

Four principles: POUR

All WCAG criteria hang on four principles. The acronym formed from their first letters is POUR. They are easiest to understand through the people who rely on them.

1. Perceivable

Information has to be provided in a form that the user can receive with at least one sense.

A blind person will not see a product photo, but will hear its description if the author wrote one. A Deaf person will not hear an instructional video, but will read the captions. This principle includes, among others, text alternatives (1.1.1), captions (1.2.2), contrast (1.4.3) and not relying on colour alone (1.4.1).

A typical mistake: a button with only a magnifying-glass icon and no name. The screen reader then simply announces "button".

2. Operable

The interface must be operable in different ways, not only with a mouse.

Someone with a hand tremor uses the keyboard. Someone paralysed from the neck down uses voice control or a mouth-operated switch. Here you will find keyboard operation (2.1.1), no keyboard traps (2.1.2), visible focus (2.4.7) and minimum touch target size (2.5.8).

A typical mistake: a menu that opens only on mouse hover.

3. Understandable

The content and the behaviour of the interface must be predictable and understandable.

A person with dyslexia or short-term memory problems will get lost if a form clears all fields after an error, or shows the message "Invalid data" without saying which data. This principle covers the language of the page (3.1.1), predictable behaviour (3.2.x) and help with errors (3.3.x).

A typical mistake: a menu whose items are in a different order on every subpage. Anyone who memorises the layout of a page instead of reading it every time gets lost every time.

4. Robust

The code must be correct and described well enough for assistive technologies to interpret it — today and in a few years.

In practice this is mainly about criterion 4.1.2: every interactive element must have a programmatically available name, role and state. Plus 4.1.3: status messages ("Added to cart") must be announced without moving focus.

A typical mistake: a <div> styled as a toggle, which looks like a button but is plain text to a screen reader.

Levels A, AA and AAA

Each criterion is assigned a level:

  • A — the minimum. Without it, some people cannot use the content at all.
  • AA — the standard. This is the level that law in the EU and in Poland refers to.
  • AAA — the highest level, for selected content.

WCAG 2.2 has 31 criteria at level A, 24 at AA and 31 at AAA (numbers counted from the specification).

How the W3C assigned the levels

A level does not mean "importance". The W3C states plainly that every criterion is important for some group of users, and choosing the target level is a policy decision of the organisation. The assignment was based on questions such as (Understanding Conformance):

  • whether assistive technology can work around the problem by itself,
  • whether it can be met for every page and every type of content,
  • whether an author can learn it in a reasonable time (the W3C speaks of "a week of training or less"),
  • whether the requirement limits functionality or appearance.

Level A criteria are usually things that cannot be worked around and that can be implemented everywhere without redesigning the project. AAA criteria are often expensive or impossible for some content — e.g. sign language interpretation of every recording.

Five conformance requirements

"We meet AA" means more than "we went through a list of criteria on a few pages". The specification sets five requirements (WCAG 2.2, Conformance):

  1. The whole level — all A and AA criteria, not "most of them".
  2. Full pages — you cannot exclude part of a page. This also applies to every responsive version.
  3. Complete processes — if a purchase takes five screens, all five must conform. An accessible cart with an inaccessible payment step is an inaccessible shop.
  4. Only accessibility-supported ways of using technologies — you cannot rely on something that screen readers and other tools do not support.
  5. Non-interference — even a non-conforming part must not block the rest of the page. Four criteria always apply: audio control (1.4.2), no keyboard trap (2.1.2), three flashes or below threshold (2.3.1), and pause, stop, hide (2.2.2).

Point 3 is the one most often skipped. An audit of the home page and three subpages says nothing about whether someone with a screen reader can pay for an order.

Same diagnosis, different needs

This is the most important section of the article, because it explains why WCAG is written the way it is.

Colour blindness is not one condition

Colour vision deficiency affects about 1 in 12 men (8%) and 1 in 200 women (0.5%) (Colour Blind Awareness, MedlinePlus). One word, however, covers several different phenomena (NEI):

TypeWhat happensPrevalence in men
Deuteranomalyreduced sensitivity to green; some greens look redderapprox. 5% — the most common
Protanomalyreduced sensitivity to red; reds look greener and darkerapprox. 1%
Deuteranopia / protanopiaone type of cone is missing; red and green cannot be told apartapprox. 1% each
Tritanomaly / tritanopiaproblems with blue and yellow, also with pink and purplerare, equally common in women and men
Achromatopsia (monochromacy)no colour vision, often poor acuity and sensitivity to lightapprox. 1 in 33,000 people

On top of that, there are three things that are usually forgotten.

Severity is a spectrum. Anomalous trichromacy (the "-anomaly" ending) covers everything from almost normal colour vision to almost none. Roughly half of the people have a mild form, half a moderate or severe one. Perception changes with lighting. And people with a severe form often believe they have a mild one (Colour Blind Awareness).

Deficiencies can be acquired. They can be caused by diabetes, glaucoma, macular degeneration, multiple sclerosis, Parkinson's disease and some medications. With age the lens yellows and absorbs more blue light. In a Smith-Kettlewell study (about 900 people aged 58–102), about 45% of people in their mid-seventies and about two thirds of people in their mid-nineties had problems distinguishing blue from yellow (HealthDay on the study by Schneck et al.). So your customers aged 70+ may struggle with a combination that designers consider "colour-blind safe".

Simulators only approximate. Chrome DevTools lets you emulate protanopia, deuteranopia, tritanopia and achromatopsia (Chrome DevTools). These are only the complete forms — the most common one, deuteranomaly, at any severity, is not simulated there. A 2016 study showed that popular simulators, including Coblis, reproduce deuteranopia inaccurately (Lillo et al., Psicothema).

What does this look like from the user's perspective? Richard Rutter, a designer with strong protanomaly, described how dark red links without underlines were simply invisible to him (clagnut.com). Joshua Nolte, who has deuteranopia, lost hours re-entering data in a form because the error was marked only with a red border — he only found out about it from a friend (Level Access).

What WCAG does about it

WCAG has no rule saying "design for deuteranopia". And that is a good thing, because such a rule would help one group at the expense of others. Instead there are two requirements that work regardless of the type of deficiency:

  • 1.4.1 Use of Color (A) — colour must not be the only carrier of information. A second, visible cue is needed: text, an icon, a pattern, an underline, or a lightness difference of at least 3:1 (Understanding 1.4.1).
  • 1.4.3 Contrast (Minimum) (AA) and 1.4.11 Non-text Contrast (AA) — calculated from luminance, i.e. lightness, not from hue. The W3C designed this formula precisely so that hue would not be decisive (Understanding 1.4.3). Light and dark stay light and dark regardless of which cones are working.

From practice (editorial opinion): design "for the loss of a channel", not for a specific type. A simple test: a greyscale screenshot. If the order status, the form error and the chart series are still readable without colour, they will survive most variants of colour blindness — congenital and acquired.

Back to the dots from the beginning: it is enough to add a word to them ("Paid", "Payment error") or different shapes (✓ and !), and both men will read the same thing.

The same pattern applies to other disabilities

Colour blindness is the most vivid example, but the rule "same diagnosis, different needs" applies everywhere.

Low vision. The W3C distinguishes four different problems: poor acuity, sensitivity to light, poor contrast sensitivity, and field-of-vision loss — central, peripheral or scattered (W3C). Someone with tunnel vision needs something different from someone with central vision loss. In a WebAIM survey of people with low vision, about 30% used magnification of 200–400%, and 18% above 400%. More than half used some kind of high-contrast mode, and most of them preferred light text on a dark background (WebAIM Low Vision Survey; data from 2018, no newer data available). That is why WCAG does not tell you to set one "large" font size. It requires the page to work when zoomed to 200% (1.4.4) and at a width of 320 px without scrolling in two directions (1.4.10).

Blind people. They use different screen readers, on different devices and with different levels of proficiency. In the latest WebAIM survey (July–August 2026, 1,780 people), 70% of respondents used more than one screen reader on a computer, and more than 91% also used a screen reader on their phone (WebAIM Screen Reader Survey #11). A page "tested in NVDA" has not yet been tested in VoiceOver on an iPhone.

Deaf and hard-of-hearing people. For some Deaf people the first language is a sign language, and the written national language is a second one (W3C). Captions will help someone who lost their hearing as an adult, but they will not replace Polish Sign Language (PJM) for someone who reads Polish as if it were a foreign language. In a study by the Polish Ministry of Digital Affairs, Deaf participants also pointed to contrast: yellow text on a white background "blended in" (MC, 2025).

Motor disabilities. One person with a hand tremor uses a mouse but cannot hit small buttons. Another moves around using only the keyboard. A third says "click Save" to a voice control program — and if the button has the accessible name "Submit form" while the screen shows "Save", the command will not work. Hence criterion 2.5.3 Label in Name and the new 2.5.8 Target Size.

Cognitive disabilities. Dyslexia, ADHD, memory impairments, autism, dementia and anxiety are completely different needs. WCAG 2.2 itself admits that even level AAA does not meet all the needs of people with cognitive disabilities. It is complemented by the W3C document "Making Content Usable" (COGA).

Vestibular disorders. Parallax and animated scrolling can trigger dizziness and nausea lasting for hours. Facundo Corradini described this after a bout of labyrinthitis (A List Apart). The technical solution is simple: respect the system setting prefers-reduced-motion.

Situations and age. A broken arm, sunlight on a phone screen, noise on a train. Poland has 9.8 million people aged 60+ (about 26% of the population), and many of them do not consider themselves people with disabilities, even though they see and hear less well (MC, 2025).

The conclusion for the whole article

WCAG phrases its criteria as an outcome to achieve ("information is not conveyed by colour alone", "the target is at least 24 px or has sufficient spacing"), not as a recipe for one user. That is its strength: one criterion covers the whole spectrum. But it is also the reason why conformance cannot be fully measured by an automated tool. A tool will check whether an image has an alt attribute. It will not check whether the description makes sense to someone who cannot see the image.

What changed in WCAG 2.2 compared with 2.1

WCAG 2.2 adds 9 criteria and removes one. It does not change existing criteria (What's New in WCAG 2.2). The main beneficiaries are — as in 2.1 — people with cognitive disabilities, people with low vision and people using mobile devices.

No.NameLevelWhat to doWho it helps
2.4.11Focus Not Obscured (Minimum)AAThe focused element must be at least partially visible — it must not be fully hidden, e.g. by a sticky bannerkeyboard and voice control users
2.4.12Focus Not Obscured (Enhanced)AAAThe focused element is fully visibleas above
2.4.13Focus AppearanceAAAA focus indicator at least as large as a 2 px outline, with a contrast change of ≥ 3:1people with low vision, older people, keyboard users
2.5.7Dragging MovementsAAEvery drag has an alternative using clickspeople with tremors, voice or switch users
2.5.8Target Size (Minimum)AAA target is at least 24 × 24 px or has sufficient spacing from its neighbourspeople with tremors or spasticity, touch screen users
3.2.6Consistent HelpAHelp (contact, chat, FAQ) is in the same place on consecutive pagespeople with cognitive disabilities
3.3.7Redundant EntryADo not ask for the same data twice in one processpeople with memory or motor impairments
3.3.8Accessible Authentication (Minimum)AALogging in does not require memorising, transcribing or solving puzzles — or it provides help (pasting, a password manager)people with dyslexia, dyscalculia, memory problems
3.3.9Accessible Authentication (Enhanced)AAAAs above, without the "recognise an object in a picture" exceptionas above

What was removed: 4.1.1 Parsing

Criterion 4.1.1 required correct HTML syntax: closed tags, unique identifiers and so on. The W3C considered it obsolete. Browsers learned long ago to tolerate syntax errors, and assistive technologies no longer parse HTML themselves. The problems that actually harm users are caught by other criteria, e.g. 1.3.1 and 4.1.2 (W3C, 4.1.1).

If a contract or regulation requires conformance with WCAG 2.0 or 2.1, the W3C notes that 4.1.1 may still have to be reported. However, errata to those versions added that for HTML and XML content the criterion is always considered satisfied.

Three myths worth correcting

Myth 1: "Focus Visible moved from AA to A". No. Criterion 2.4.7 is still at level AA (WCAG 2.2). The W3C stresses that new versions of WCAG do not change existing criteria — the only exception is the removal of 4.1.1.

Myth 2: "A new AA requirement: a 2 px focus outline with 3:1 contrast". That is criterion 2.4.13 Focus Appearance, which is at level AAA. At level AA the focus must be visible (2.4.7), not obscured (2.4.11), and its indicator must have a 3:1 contrast against its surroundings (1.4.11).

Myth 3: "The criterion number tells you its level". New criteria were appended at the end of the guidelines so as not to change the old numbers. That is why 2.4.11 (AA) comes after 2.4.10 (AAA).

What about WCAG 3?

WCAG 3 is a separate, still draft document (latest Working Draft — March 2026) with a new scoring model. It is not a standard yet and will not replace WCAG 2 for years to come. According to AbilityNet's estimates, the final recommendation will not appear before 2028 (W3C: WCAG 3, AbilityNet). Today, WCAG 2.2 is what counts for conformance.

Criteria in practice: how to check them during an audit

Below are the criteria that most often decide whether someone can get things done on a website. For each: how to check it, the most common mistake, and who it affects. The selection is based on data: in the Polish monitoring of public websites for 2025, criterion 1.3.1 was not met by any of the 100 websites examined, 2.4.2 was not met by 90, 4.1.2 by 85, and 2.4.3 by 84 (MC, monitoring 2025).

CriterionHow to checkTypical mistakeWho it affects
1.1.1 Non-text Content (A)axe/WAVE will find a missing alt. Whether the description makes sense is judged by a human, ideally with a screen readeralt="image123.jpg"; a description of a decoration that should have alt=""blind people
1.3.1 Info and Relationships (A)heading and landmark view (WAVE: Structure, NVDA+F7), screen reader testbold text instead of a heading; a table built from <div>s; a label not associated with its fieldblind people, cognitive
1.3.5 Identify Input Purpose (AA)check the autocomplete attributes on personal data fieldsmissing autocomplete="email", "name", "street-address"motor, cognitive
1.4.1 Use of Color (A)greyscale screenshot; links in text — underline or 3:1 contrast against the textan error marked only with a red bordercolour blindness, low vision
1.4.3 Contrast (Minimum) (AA)axe/WAVE + a colour picker (e.g. Colour Contrast Analyser) for text on photos and gradientsgrey helper text at 3:1; a placeholder as the only labellow vision, older people
1.4.10 Reflow (AA)a 320 px window or 400% zoom at 1280 pxa horizontal scrollbar, a cut-off menulow vision
1.4.11 Non-text Contrast (AA)colour picker on field borders, icons, the focus indicatora light grey field border on a white backgroundlow vision
2.1.1 / 2.1.2 Keyboard, No Keyboard Trap (A)put the mouse away and Tab through the whole processa hover-only menu; a dialog you cannot leavemotor, blind people
2.4.1 Bypass Blocks (A)first Tab on the page → does "Skip to content" appear?no skip link, or a link to a non-existent idkeyboard, screen readers
2.4.3 Focus Order (A)Tab through the page and the dialogsfocus stays under the dialog; after closing it returns to the top of the pagekeyboard, screen readers
2.4.7 / 2.4.11 Focus Visible and Not Obscured (AA)Tab with a sticky header and a cookie banneroutline: none without a replacement; focus under the bannerkeyboard, voice
2.5.3 Label in Name (A)compare the button text with the accessible name (DevTools → Accessibility)visible "Find", but aria-label="Search"voice control
2.5.8 Target Size (Minimum) (AA)axe with the wcag22aa tag + measurement in DevTools16 px icons next to each other in a tabletremors, touch
3.2.2 On Input (A)change an option in a drop-down list with the keyboardthe page reloads as soon as an option is selectedscreen readers, cognitive
3.3.1 Error Identification (A)submit an empty formonly a red border, no text; a message not associated with the fieldeveryone, especially blind people
3.3.8 Accessible Authentication (AA)try pasting the password and using a password managerpasting blocked; "enter the 3rd and 7th character of your password"; a text CAPTCHA with no alternativedyslexia, memory
4.1.2 Name, Role, Value (A)screen reader: does it announce "button, collapsed/expanded"?<div onclick>; an icon button without a nameblind people, voice
4.1.3 Status Messages (AA)add to cart with a screen reader onthe message is visible but not announcedblind people

Example: how to measure 2.5.8

Criterion 2.5.8 has five exceptions. The most useful one is the spacing exception: draw a circle with a 24 px diameter around the centre of a small target. If it does not intersect another target or the circle around a neighbouring small target, the criterion is met (Understanding 2.5.8).

An example from goatcms.com: the footer links are only 18 px tall, but their centres are 25–26 px apart. Circles with a 24 px diameter do not touch, so AA is met. AAA (2.5.5, 44 × 44 px) — no longer.

The remaining exceptions: there is an equivalent, larger target; the link is within a sentence (inline); the size of the control is determined by the browser; the size is essential (e.g. pins on a map).

Example: what "cognitive function test" means in 3.3.8

According to the W3C, it is a task that requires remembering, transcribing or transforming information (Understanding 3.3.8). Typing a username and password is acceptable if the site lets a password manager do it, or allows pasting. The following, however, will not pass:

  • blocking paste in the password field,
  • asking for "the first, third and fifth character of your password",
  • a CAPTCHA with a maths problem,
  • an SMS code that has to be retyped manually, with no way to paste or autofill it.

Hardware keys, passkeys (WebAuthn) and system biometrics are not cognitive function tests. The criterion applies to logging in, not to creating an account.

How to check conformance

The W3C describes the evaluation process in the WCAG-EM methodology. Its second version, from July 2026, also covers applications (WCAG-EM). Five steps:

  1. Scope — what we evaluate and at what level (e.g. the whole shop, WCAG 2.2 AA).
  2. Exploration — what page types, key processes and technologies there are.
  3. Sample — representative pages and complete processes (registration, purchase, contact).
  4. Evaluation — every criterion on every page in the sample.
  5. Report — results, evidence, priorities.

The W3C is also clear: no tool alone can determine whether a website meets the standard. It takes evaluation by a human with accessibility knowledge (W3C: Evaluating). In practice testing consists of four layers.

Layer 1: automated tests — the first sieve

Before I get to the tools, a correction of a common misunderstanding: NVDA is not an automated testing tool. It is a free screen reader for Windows used by thousands of blind people. You test with it manually, in layer 3. There are libraries that can drive real NVDA and VoiceOver from tests (e.g. Guidepup with a Playwright integration), but that is a niche, not a replacement for listening manually.

axe DevTools (axe-core). A library by Deque on which many other tools are built, including Lighthouse. The browser extension shows errors with a reference to the criterion and a code snippet. Three things worth knowing (axe-core, rule list):

  • The "Needs review" / "incomplete" section is not a junk drawer. It is a list of places where the tool cannot decide and needs a human.
  • Of the new WCAG 2.2 criteria, axe checks only 2.5.8 (the target-size rule). This rule is disabled by default — you have to enable the wcag22aa set.
  • Deque states that axe detects 57% of issues on average. These are the vendor's own data (2021), counted by the number of issues found, not by the number of criteria (Deque). The result is high partly because contrast errors are widespread and easy to detect.

WAVE (WebAIM). It overlays icons on the page: red errors, contrast errors, yellow alerts, green accessibility features, and the structure of headings and landmarks (WAVE). Alerts are things that *may* be a problem — e.g. a skipped heading level or several "Read more" links — and require a human decision. The structure view is useful even for non-technical people.

Lighthouse (Chrome). The accessibility score is a weighted average of selected axe audits, with weights of 10, 7 or 3 (Chrome: scoring). Each audit is pass/fail. Audits marked as manual do not count towards the score at all, and the weights table does not include the target-size rule. A Lighthouse score of 100 means the page passed this set of automated rules — nothing more.

How much do automated tools really find? The numbers circulating online measure different things:

  • In 2017 the UK GDS team built a page with 143 deliberately introduced barriers and ran 10 tools on it. The best single tool found about 40% of the barriers. All of them together — 71%. 29% of the barriers were found by none (GDS).
  • In 2023 Adrian Roselli compared a manual review of a single page with free tools. Manually he found 37 errors across 18 criteria. axe reported 2, WAVE — 0 (Roselli).
  • Deque, counting the volume of issues across thousands of audits: 57%.

All three results can be true at the same time. Automated tools are great at catching frequent, mechanical errors (contrast, missing alt, missing label), so "by volume" they do well. They do worse with errors that require understanding the context: whether the image description makes sense, whether the focus order is logical, whether a message is announced at the right moment.

The scale of the problem shows that even this sieve is necessary. In the WebAIM Million 2026 report, automatically detected WCAG errors were found on 95.9% of the million most popular home pages, 56 per page on average. The most common: low text contrast (83.9% of pages), missing alternative text (53.1%), unlabelled form fields (51%), empty links (46.3%), empty buttons (30.6%) and a missing document language (13.5%) (WebAIM Million).

From practice: run axe in end-to-end tests on every change (with the wcag22aa tag), and WAVE manually when reviewing new templates. Treat Lighthouse like a thermometer — it tells you something is wrong, not that everything is fine.

Layer 2: manual tests — 30 minutes without a mouse

This is where you will catch most of what the automated tool does not see. A scenario you can do without specialised software:

  1. Keyboard only. Put the mouse away. Go through the whole key process using Tab, Shift+Tab, Enter, Space, the arrow keys and Esc. Check:
    • whether the first Tab shows a skip link,
    • whether you can always see where the focus is (also under a sticky header and a cookie banner),
    • whether the order makes sense,
    • whether you can leave every dialog with Esc and the focus returns to where it came from,
    • whether nothing happens "by itself" when you select an option from a list.
  2. Zoom. 200% zoom — does the text get cut off? A 320 px wide window (or 400% zoom) — does a horizontal scrollbar appear?
  3. Text spacing (1.4.12). Using a bookmarklet or a user style, set line height to 1.5, paragraph spacing to 2×, letter spacing to 0.12 and word spacing to 0.16 of the font size. Does the text overlap?
  4. Contrast. Use a colour picker to check text on photos, gradients and in hover states that the automated tool does not see.
  5. Without colour. Turn on greyscale in the system, or take a screenshot and desaturate it.
  6. Motion. Turn on "reduce motion" in the system and check whether animations stop.
  7. High contrast mode (Windows: Contrast themes). Do icons, field borders and the focus indicator disappear?
  8. Forms. Submit an empty form, then one with invalid data. Is the error described in words, next to the field, and does the focus go to the first invalid field? Does the data stay?
  9. Structure. The browser tab title — does it tell me where I am? The page language in <html lang> — does it match the content?

The W3C has a ready-made "Easy Checks" list for this stage (W3C). The organisation itself stresses that it is a quick check, not a verdict.

Layer 3: assistive technologies — NVDA, VoiceOver, TalkBack

Some context first. According to WebAIM survey #11 (2026), the primary desktop screen reader is JAWS (55%), followed by NVDA (32.9%) and VoiceOver (6.5%). In Europe JAWS and NVDA are neck and neck (42.8% and 42.3%). On phones iOS dominates (73.3%) (WebAIM #11). JAWS is paid, so in practice teams most often test with the free NVDA. The survey is not representative (an uncontrolled sample, more than half of the responses from North America), but it shows the proportions well.

From practice — a minimal test matrix:

SystemScreen readerBrowser
WindowsNVDAFirefox or Chrome
macOSVoiceOverSafari
iOSVoiceOverSafari
AndroidTalkBackChrome

NVDA cheat sheet (from the NV Access documentation and WebAIM):

  • NVDA key: Insert (or Caps Lock after changing the settings),
  • Ctrl: stops speech immediately,
  • H / Shift+H: next / previous heading; 1–6: heading of that level,
  • K: link, F: form field, B: button, D: landmark, T: table,
  • NVDA+F7: elements list (links, headings, landmarks),
  • NVDA+Space: toggles between browse mode and focus mode (usually happens automatically, with a sound),
  • Tools → Speech Viewer: a window with the text of what NVDA says — very useful for sighted testers.

VoiceOver on macOS cheat sheet (Apple, WebAIM):

  • Cmd+F5: turn on / off,
  • VO = Ctrl+Option (or Caps Lock),
  • VO+U: rotor — lists of headings, links, landmarks, form controls,
  • VO+Cmd+H: next heading; VO+Cmd+L: link; VO+Cmd+J: form control,
  • VO+Shift+↓ / ↑: interact with a group / stop interacting,
  • in Safari, enable "Press Tab to highlight each item on a webpage" in the settings.

VoiceOver on iPhone (WebAIM): swipe right/left — next/previous element; double tap — activate; two-finger rotation — rotor; two-finger swipe down — read all. Shortcut: triple-click the side button (after setting it up in Accessibility).

TalkBack on Android (Google): swipe right/left — next/previous element; double tap — activate; scroll with two fingers; TalkBack menu — swipe down then right, or a three-finger tap; swiping up and down changes the navigation mode (headings, links, controls). Shortcut to turn it on: hold both volume keys for a few seconds.

What to listen for. For every interactive element the screen reader should announce four things: the name ("Search"), the role ("button"), the state ("expanded", "checked", "invalid") and possibly the value ("3 items"). Plus announcements: does the screen reader say anything after adding to the cart, submitting a form or changing the page in a SPA?

A good first test: go through the page by headings only (H in NVDA, the rotor in VoiceOver). 67.8% of screen reader users look for information on a long page exactly this way (WebAIM #11). If the headings alone do not let you understand the layout of the page, you have a problem with 1.3.1 and 2.4.6.

Where do screen reader users get stuck most often? In WebAIM survey #10 (2024), CAPTCHA tops the list of problems by a clear margin. Next: widgets (menus, tabs, dialogs) behaving differently than expected, unclear links and buttons, unexpected screen changes, lack of keyboard support, missing image descriptions and complex forms. WebAIM notes that this order has barely changed in 14 years (WebAIM #10).

An honest caveat. A sighted tester with a screen reader is not a screen reader user. They listen differently (more slowly), know the code and subconsciously glance at the screen. WebAIM advises turning off the monitor for at least a moment during testing. In NVDA the screen curtain is for exactly that (NVDA+Ctrl+Esc).

Layer 4: testing with people

The W3C describes this precisely: tests with users with disabilities find problems that a conformance evaluation will not. But on their own they do not determine conformance, and the opinion of one person should not be generalised to a whole group (W3C: Involving Users). After the section on colour blindness the reason is obvious: one person with colour blindness is one point on the spectrum.

Why is it worth it? A study by Power et al. (CHI 2012) with 32 blind users on 16 websites showed that only about half of the problems they encountered were covered by WCAG 2.0 at the time. The W3C disputed the classification of some of the problems, but the direction of the conclusion — conformance is not the same as usability — is widely accepted (ACM). Léonie Watson, a blind accessibility engineer, puts it like this: technically accessible is good, usefully accessible is better (Smashing Magazine).

Cannot afford research? Start with one person who uses a screen reader and one with a motor disability, ask them to go through one key process, and do not interrupt. Non-governmental organisations working on accessibility often act as intermediaries for such tests.

What not to spend money on: overlays

Overlays are scripts that promise "automatic WCAG conformance" after pasting one line of code. More than a thousand practitioners and users have signed the Overlay Fact Sheet, which explains why this does not work (Overlay Fact Sheet). In 2025 the US FTC fined accessiBe one million dollars and banned it from making WCAG conformance claims without evidence (FTC). A blind customer, Patrick Perdue, described in the New York Times how an overlay that was supposed to help him broke a shop's cart and search for him (Benton). A home-made "high contrast" toggle has a similar effect — in the Polish monitoring, such toggles were found to hide content that was readable in the normal view (MC, monitoring 2025).

Getting to AAA — and whether to try at all

In the specification itself, the W3C writes that it does not recommend requiring level AAA as a general policy for entire sites, because for some content it is not possible to meet all AAA criteria (WCAG 2.2, cc1). That note is worth reading together with the next one: the W3C encourages reporting progress on criteria above the level achieved.

From practice — a sensible strategy: AA across the whole site, plus selected AAA criteria where they are cheap or especially important for your users. The split below is an editorial opinion, not a W3C classification.

AAA criteria that are usually worth implementing straight away:

  • 2.5.5 Target Size (Enhanced) — 44 × 44 px for buttons. Worth it on phones anyway.
  • 2.4.13 Focus Appearance — a solid 2–3 px outline in a contrasting colour. One CSS rule.
  • 2.4.12 Focus Not Obscured (Enhanced) — scroll-padding under sticky elements.
  • 2.3.3 Animation from Interactions — prefers-reduced-motion.
  • 1.4.6 Contrast (Enhanced) — 7:1 for body text. Usually a darker grey is enough.
  • 3.3.9 Accessible Authentication (Enhanced) — passkeys, email link login, no image CAPTCHA.
  • 2.4.10 Section Headings and 3.2.5 Change on Request — a matter of discipline in content and interactions.

AAA criteria that are usually implemented selectively:

  • 1.2.6 Sign Language — a sign language interpreter in every recording. Sensible for official, health and educational content aimed at Deaf people.
  • 1.2.7 Extended Audio Description — pausing the video to fit in the description. Requires editing.
  • 3.1.5 Reading Level — text understandable to someone who has completed lower secondary education, or a simplified version. Hard for legal and medical content. A compromise is a plain-language summary at the beginning.
  • 1.4.8 Visual Presentation — among other things, a choice of text and background colours and a line width of up to 80 characters.

How to report it? An honest statement reads, for example: "WCAG 2.2 AA — full conformance; additionally we meet 2.4.13, 2.5.5 and 2.3.3 (AAA)". That is worth more than a promise of "AAA" that cannot be kept on every page.

Case study: goatcms.com and the standard GOAT module

GOAT is a code generator for applications in Go and Angular. goatcms.com is its website, documentation and panel. The look and behaviour of the public pages, the admin panel, forms, the shop and the AI assistant come largely from the standard module — goatcore and the generators in the goatcms module. The same modules are also used by other projects built on GOAT, including troska-na-zawsze.pl and pszczelipark.

On 17 October 2026 a series of changes titled "correct WCAG i WAI-ARIA" landed in the module and on the website: more than 100 files in goatcore, 26 in the goatcms generators and 26 in the website itself.

Why fix the module and not the website

Editorial opinion: this is the most important decision in this story. When the skip link, the focus outline or a correct login form live in the module, every application built on GOAT gets them at the next goat re. When they live in a specific website's template, every project has to repeat them — and each one will get it slightly wrong in its own way.

This advantage has a flip side: a bug in the module also lands everywhere. That is why changes in the module must have tests, and visual changes must be checked on all projects that use it. The GOAT team wrote this rule into the project documentation.

What was changed

A selection, grouped by what the user gains. In brackets — the criterion that the code comments or the nature of the change point to.

Keyboard navigation and focus

  • Every layout variant starts with a "Skip to main content" link. All page types, including the cart and the order, have a main element with the target identifier (2.4.1).
  • Semi-transparent focus outlines were replaced by one global rule: outline: 3px solid in the --focus colour with a 2 px offset. The old outlines had a contrast of 1.35–2.02:1 on a white background, the new one — 5.24:1 (2.4.7, 1.4.11). A code comment points to a less obvious detail: unlike box-shadow, outline survives Windows high contrast mode.
  • The cookie banner measures its height and sets scroll-padding-bottom on the page so that the focused element does not hide under the banner (2.4.11 — a new WCAG 2.2 criterion).
  • In the admin panel, after every view change the tab title is updated and the focus moves to the h1 heading of the new view. Without this, the screen reader in a SPA stays silent after a menu click, and the focus remains on a link that no longer exists (2.4.2, 2.4.3).
  • The change-password dialog was a custom div with role="dialog", without focus management. Now it is a native <dialog> element opened with showModal(): it traps focus, closes with Esc and returns focus to the button that opened it (2.4.3, 2.1.2).
  • After a record is deleted from a list, the focus moves to the list heading, because the row it came from no longer exists (2.4.3).

Contrast

  • A new --control-border token: form field borders changed colour from #aebbad (2.00:1 on white) to #7f8e80 (3.45:1) (1.4.11).
  • The helper text --text-subtle changed colour from #6c786e to #5f6b61. Against the page background the contrast rose from 4.24:1 (below the AA threshold) to 5.13:1 (1.4.3).

Predictability and language

  • The language switcher was a <select> list that reloaded the page the moment the option changed — a classic violation of criterion 3.2.2. A keyboard user browsing the options with the arrow keys was taken to another language version before choosing anything. Now it is a button with a list of links (the disclosure pattern from the ARIA Authoring Practices): aria-expanded, closing with Esc, and every link has hreflang, lang and the language name in that language — "Polski", "Deutsch", "中文" (3.2.2, 3.1.2, 4.1.2).
  • The SSR page generator selects content by address and language. Previously translations shared an address, so a page with <html lang="en"> could display text in another language. A screen reader could then read it with English pronunciation (3.1.1).

Names and roles

  • The logo link had aria-label="Home", even though the image had a different description. Now the name comes from the image itself ("GOAT – home page"). The same in the panel. This is about voice control: the command must match what is visible (2.5.3).
  • The navigation marks the current page with the aria-current attribute, and the article table of contents marks the current section (1.3.1).
  • The dashboard chart (drawn in a <canvas>) got role="img" with a description and a hidden table with the same data. With "reduce motion" on, it turns off the animation (1.1.1, 1.3.1, 2.3.3).
  • In the AI assistant chat, the speakers used to be distinguished only by the colour and position of the bubble. Now every message starts with a visually hidden prefix "You:" or "Assistant:", and the conversation window has role="log" (1.3.1, 1.4.1, 4.1.3). This is exactly the same problem as the dots at the beginning of the article, just in a different place.
  • Tables in articles have column headers th scope="col". Scrollable tables and code blocks can be scrolled with the keyboard (1.3.1, 2.1.1).

Forms and messages

  • Every field in forms generated by GOAT gets required, aria-invalid and aria-describedby pointing to the error message (3.3.1, 3.3.2).
  • The "Log in" button is no longer disabled while the form is invalid. A disabled button says nothing — the user does not know what is missing. Now clicking on an empty form moves the focus to the first invalid field, and the screen reader reads the message that the field is required (3.3.1).
  • Success and error messages go into permanent role="status" and role="alert" regions that exist on the page from the start. Regions added to the page at the moment a message appears are sometimes skipped by screen readers (4.1.3).
  • The cart announces the new total after every change, and the "Remove" buttons contain the visually hidden product name. The screen reader no longer lists five identical "Remove, button", but says which product will disappear from the cart (4.1.3, 2.4.6).

Tests

  • Go unit tests check, among other things, that every layout variant starts with a skip link, that the logo link has no overriding aria-label, and that aria-current points to the correct element.
  • A Playwright login test: empty form → focus on the first field, aria-invalid="true" and a description saying the field is required; the first Tab on the page lands on the skip link.
  • The website's smoke test runs axe-core (with tags up to wcag22aa) on every visited page, in all languages, and requires zero violations. It also checks the skip link and that the page lang matches the content language.

What the live test showed

On 17 October 2026 I ran axe-core 4.10.2 on the production website with the WCAG 2.0–2.2 A/AA rule set and best practices.

PageViolationsFor manual review
Home page /pl013 (contrast)
Documentation /doc/pl/start00
Login /app/login012 (contrast)

Twelve of the 13 "for manual review" elements on the home page are decorative arrows hidden from screen readers (aria-hidden), for which axe cannot calculate contrast. The thirteenth is the cookie banner text, which sits on top of other content, so axe does not know what its background is. After inspection — false alarms. This is a good example of what the "incomplete" section is: not an error, but a question for a human. I did not analyse the elements on the login page in detail.

Plus a few measurements in the browser:

  • the first element Tab lands on is the skip link; the page has lang="pl", landmarks and logical headings,
  • at a width of 320 px the home page and the documentation do not scroll horizontally (1.4.10),
  • the footer links meet 2.5.8 thanks to the spacing exception (described above), but would not meet AAA 2.5.5,
  • the login form has autocomplete="username" and "current-password" and no CAPTCHA — this helps with 3.3.8, because a password manager will do the rest.

One small thing that axe did not report also turned up: the scrollable code blocks in the documentation have tabindex="0", so they can be scrolled with the keyboard, but they have no role or name. A screen reader user Tabs onto a stop without knowing what it is. For example, role="region" with the label "Code example" would be enough.

What is still left

The list below is an editorial assessment based on a code review, not the result of a full audit:

  1. Automated tools see only part of the application. axe runs in the test of the public pages and the login page. It does not cover views after logging in, open dialogs or forms in an error state — that is, the parts that were changed the most.
  2. The new WCAG 2.2 criteria are covered only partially. 2.4.11 (cookie banner) — yes. 2.5.8 was not audited directly: the checkbox is 20 × 20 px (probably saved by its clickable label), and the "×" button in the image picker has no minimum size. 3.3.7 (repeating the address in an order), 3.2.6 (consistent help) and 2.5.7 (dragging blocks in the content editor) — untouched.
  3. Language of parts (3.1.2). Form fields still contain hard-coded English texts ("Select image", "Remove"), and a fragment of the Word import is in Polish in the other language versions too (although it is marked with lang="pl").
  4. Gallery. The link that opens an image without a caption now has a name, but the enlarged image itself in the preview window still has an empty alt.
  5. No forced-colors rules for high contrast mode (although the switch to outline helps a lot here).
  6. Unnecessary tab stops. Every table and every code block is focusable, even when there is nothing to scroll.
  7. No trace of tests with screen readers and with people. The repository has code tests and an automated tool, but no documented scenario such as "buying a licence with NVDA" or "logging in with VoiceOver on an iPhone".

The proposed next step for the module: a short accessibility checklist in every PR, axe in the panel's e2e tests (including error states and open dialogs), a manual NVDA + VoiceOver scenario for every release, and an accessibility statement that honestly lists points 2–6.

What this case teaches

Go through the list of changes again and ask about each one: would an automated tool have detected it? Insufficient contrast of helper text — yes, axe reports it. Focus that stays on a non-existent link after a view change — no. A page reloading while you browse the language list — no. A cart message that appears on the screen but is not announced — no. A button name different from its visible label — only in simple cases.

Editorial opinion: most of these fixes required a review that a scanner cannot replace: someone had to know the criteria and trace the interface the way a keyboard or screen reader user goes through it. The automated tool is useful at the end — as a guard that keeps fixed things from breaking in the next release. And point 7 of the list above shows that even this review does not replace a test with a real user.

Where this argument may be wrong

"Automated tools are enough to guard against regressions." Partly true. Once a process has passed a manual audit, axe in the tests does a good job of making sure nothing breaks in the mechanical categories. The problem starts when the automated test is the only test the website has ever passed.

"Testing with people is expensive, and the samples are small." True — and that is why the W3C does not treat it as proof of conformance. Five people do not represent the spectrum of colour blindness or all screen reader users. But even one person will find problems no auditor anticipated.

"WCAG is a minimum, not usability." The critics are right that conformance does not guarantee a convenient website. That does not mean WCAG is unnecessary: it is the only measurable, internationally agreed point of reference — and the law is based on it.

"A shared module is a shared point of failure." Yes. A change in goatcore can improve accessibility on four websites or break it on four at once. The argument about "fixing at the source" holds only if the source also has tests.

"If you cannot measure everything, why measure at all?" This article does not claim that. Measurement is necessary. The only mistake is treating it as proof.

15 minutes before publishing: a cheat sheet

  1. Run axe DevTools with WCAG 2.2 AA enabled. Also go through the "Needs review" section.
  2. First Tab: is the skip link visible? Does it work?
  3. Tab through the key process. Can you always see the focus? Is anything covering it?
  4. Open and close every dialog with Esc. Where does the focus return?
  5. Submit an empty form. Is the error described in words, next to the field?
  6. Take a greyscale screenshot. Are statuses and charts readable?
  7. 200% zoom, then a 320 px window. Does anything escape?
  8. Paste a password into the login field. Does it work?
  9. Go through the page by headings only in NVDA (H) or VoiceOver (rotor). Do you understand its layout?
  10. Add something to the cart with a screen reader on. Do you hear a confirmation?
  11. Check the tab title and the lang attribute.
  12. Turn on "reduce motion". Have the animations stopped?

If all 12 points come out fine, you do not yet have WCAG 2.2 AA conformance. What you do have is a website that most of the people in this article can use — and that was the goal from the start.

Sources

W3C standards

Law in Poland and the EU

Tools and the effectiveness of automated testing

Screen readers

Colour blindness, low vision and user experiences

GoatCMS