WCAG 2.1: criteria counts and an axe-core scan
This is the material behind the article WCAG 2.1 explained: principles, AA and 2.2 changes. In September 2026 I made three small measurements: I counted the success criteria in each WCAG version, compared the Polish accessibility act with WCAG 2.1, and ran an automated scan on ten pages of my own site. None of them assesses whether a website conforms to WCAG, mine included. The Polish version of this note is metodologia.md.
Criteria per version and level
A script downloads the three W3C Recommendations (/TR/WCAG20/, /TR/WCAG21/ and /TR/WCAG22/) and pulls out every success criterion with its level. Those addresses always serve the newest edition of a version, which for WCAG 2.1 was the 2025 edition, and the W3C says later editions keep the same criteria. I counted 4.1.1 Parsing as removed in WCAG 2.2, because the spec marks it "Obsolete and removed" there.
| Version | A | AA | AAA | Total | A + AA | Guidelines |
|---|---|---|---|---|---|---|
| 2.0 | 25 | 13 | 23 | 61 | 38 | 12 |
| 2.1 | 30 | 20 | 28 | 78 | 50 | 13 |
| 2.2 | 31 | 24 | 31 | 86 | 55 | 13 |
From 2.0 to 2.1, 17 criteria were added (5 A, 7 AA, 5 AAA), with nothing removed and no level changed. From 2.1 to 2.2, 9 were added (2 A, 4 AA, 3 AAA) and 4.1.1 was removed, again with no level changes. In the current WCAG 2.1 edition 4.1.1 is still Level A, with a note that it "should be considered as always satisfied" for HTML or XML content.
The annex to the Polish act
A second script reads the Polish digital accessibility act of 2019 (Dz.U. 2019 poz. 848) from eli.gov.pl and compares the criteria in its annex with the 50 WCAG 2.1 A and AA criteria. The annex lists 49 of them (30 A, 19 AA), with no level that differs. The one missing is 1.2.4 Captions (Live). That fits Article 3(2)(1), which excludes live-broadcast multimedia from the act, although the act itself gives no reason for leaving the criterion out.
The axe-core scan of ten pages
I ran axe-core in a clean Chromium on ten pages of cometweb.io: /, /pl, /pricing, /insight/accessibility, /tools/contrast, /pl/tools/a11y-checklist, /contact, /blog/accessibility-audit-wcag-eaa, /pl/blog/audyt-dostepnosci-wcag-eaa and /pl/glossary/wcag. That covers one page of each template, both homepages and two language pairs. The window was 1280 × 800 with reduced motion, and the cookie banner stayed as a first-time visitor sees it. I limited axe to the WCAG 2.1 A and AA rules, and its experimental rules stayed off, as they are by default.
Each of the 50 WCAG 2.1 A and AA criteria then got one outcome, starting with the most severe:
| Outcome | What it means | Criteria |
|---|---|---|
| Violation | a rule for this criterion failed on at least one page | 1 |
| Needs review | a rule couldn't decide on at least one page | 3 |
| Rules passed | the rules ran on real content and found nothing | 11 |
| Nothing to test | a rule exists, but the pages had no video, audio, meta refresh or blinking content for it | 4 |
| Experimental rule only | only an experimental axe rule covers this criterion | 3 |
| No rule | no axe-core rule covers this criterion | 28 |
When axe links a rule to a criterion, the rule tests part of that criterion. So "rules passed" means the automated part found nothing on these ten pages. For example, image-alt checks that an image has alternative text, and whether that text is right is for you to judge.
What the scan found on my site
- One violation.
color-contrast(1.4.3) on/pricing: six elements of 12 px hint text at 4.49:1 (#7e7e7eon#151515) and 3.81:1 (#757575on#191919), where 4.5:1 is required. That is a real defect on my page. - Needs review on every page.
color-contraston 88–209 elements per page, 1,460 in total. Axe gave 1,220 of them the reason "text on a gradient background", 100 "pseudo-element content", 72 "text too short to judge", 24 "overlapping backgrounds" and a few others. Alsoaria-valid-attr-valueon the navigation'saria-controls, because the menu panel it points to appears only when the menu opens, andlink-in-text-blockon the privacy policy link in the newsletter consent, which sits on a gradient. - Needs review on single pages.
aria-hidden-focusin the homepage demo preview,aria-prohibited-attron/insight/accessibilityandth-has-data-cellson/pricing.
What this data can't tell you
- Anything a person has to check: keyboard paths, focus order and visibility, screen readers, 200% zoom, reflow at 320 CSS px, and whether alt text and error messages make sense.
- What happens after interaction, such as open menus, submitted forms and dialogs.
- Mobile layouts, other browser engines and pages behind a login.
- Criteria that exist only in WCAG 2.2, and Level AAA.
- Whether any page, or cometweb.io as a whole, conforms to WCAG. The scan is a first pass, and an audit needs the manual checks above.
Files
criteria-counts.jsonandcriteria.csv: the counts and every criterion by version, level and principle, with a hash of each W3C document so a later run shows if the text changedannex-pl-2019.json: the comparison with the Polish annexaxe-scan-results.json: every violation and needs-review item with its rule, criteria, element count and reasonsaxe-wcag21-coverage.json: the outcome for each of the 50 criteriasources.json: the W3C documents, the act and the other sources I relied oncount_criteria.py,count_annex_pl.py,run_axe_scan.mjs,build_charts.py: the scripts for the counts, the annex, the scan and the two charts
To run it again: python3 count_criteria.py and python3 count_annex_pl.py need only Python. For the scan, copy criteria.csv and run_axe_scan.mjs into an empty folder, run npm i playwright@1.62.1 axe-core@4.13.0, npx playwright install chromium and node run_axe_scan.mjs. The counts should match while the W3C documents stay the same, and the scan will differ as my pages change.