Exactly what we check.
And what we don't.
This is the methodology page, not the marketing page. Every rule check, every WCAG mapping, and a plain list of what static analysis structurally cannot see — including from us.
Every free scan runs 16 rule-based checks against your page's HTML, each mapped to a WCAG success criterion, each weighted by severity. Nothing here is guessed — a check either fires or it doesn't, based on parsing the markup your server actually sends.
| Check | WCAG success criterion | Severity |
|---|---|---|
| Image missing alt attribute | 1.1.1 Non-text Content (A) | Critical |
| Placeholder-style alt text (filename, "image", "photo123") | 1.1.1 Non-text Content (A) | Moderate |
| Page language not declared | 3.1.1 Language of Page (A) | Serious |
| Missing or empty page title | 2.4.2 Page Titled (A) | Serious |
| Link with no accessible name | 2.4.4 Link Purpose (A) / 4.1.2 Name, Role, Value (A) | Serious |
| Button with no accessible name | 4.1.2 Name, Role, Value (A) | Serious |
| Form field with no label | 1.3.1 Info and Relationships (A) / 3.3.2 Labels or Instructions (A) | Serious |
| Missing h1 | 1.3.1 Info and Relationships (A) | Moderate |
| Skipped heading level | 1.3.1 Info and Relationships (A) | Minor |
| Iframe with no title | 4.1.2 Name, Role, Value (A) | Serious |
| Zoom disabled in viewport meta tag | 1.4.4 Resize Text (AA) | Serious |
| Positive tabindex value | 2.4.3 Focus Order (A) | Moderate |
| Duplicate id attribute | 4.1.1 Parsing (A) | Minor |
| aria-hidden on a focusable element | 4.1.2 Name, Role, Value (A) | Serious |
| Timed meta refresh | 2.2.1 Timing Adjustable (A) | Serious |
| Autoplaying audio or video | 1.4.2 Audio Control (A) | Moderate |
Every one of these is a property you can read straight off the parsed HTML: an attribute is missing, a heading number jumped, an id repeats. That's also their limit — a check can only exist here if the answer is decidable by parsing markup alone, with no judgement calls and no rendering.
What the deep AI audit judges
The deep audit is a different kind of check. Instead of reading text, it downloads the actual image file behind each described image and sends it to a vision model alongside the alt text, then asks a narrower, harder question: is this true? That costs us roughly 5–15¢ per page in vision-model calls, depending on image size — vision models are billed by pixel area, so a page of large hero images costs several times what a page of thumbnails does, which is why it isn't unlimited and isn't free at scale. It opens up to six meaningful images per page, not all of them — the rule checks still cover every image; the capped step is specifically the "is this true?" judgment. Paid plans run it weekly on the pages you nominate; the free tier caps it at one audit a day.
| Judgement | What it catches |
|---|---|
| Accuracy | The alt text describes something the image doesn't actually show — often a leftover from a copy-pasted template or a swapped product photo. |
| Specificity | The alt text is technically true but empty of information, like "product" on a photo of one specific boot. |
| Filename leakage | The alt text is a raw filename or CMS placeholder such as IMG_4021.jpg that was never replaced. |
| Decorative mismatch | An image that carries no information of its own — a spacer, a repeated background flourish — has been given a description anyway, forcing screen reader users to sit through noise. |
This only works because the image file is actually opened. Every check in the table above it works from text alone and would score "IMG_4021.jpg" as present and non-empty. It takes looking at the picture to know that's not alt text, it's a filename.
What GotAlt cannot detect
This is the part most scanners bury in a footnote. We're putting it in a heading, because a tool that won't tell you what it misses is more dangerous than no tool at all — it lets you believe a passing report means something it doesn't.
Computed colour contrast
We read the HTML your server sends using Cloudflare's HTMLRewriter, which parses markup only — it has no CSS engine and no layout engine, so it never computes the final rendered colour of any element, let alone what sits behind it. Contrast requires an actual paint step. Our free contrast checker is a client-side colour-pair tool for this reason: you supply two colours, it doesn't try to read them off your live page.
Keyboard traps
Finding a trap means actually pressing Tab repeatedly and observing whether focus can ever leave a component. That's a behavioural test carried out over time in a real browser, not a static property of any single HTML element — there's nothing in the markup that says "you can get in here but not out."
Focus order and visibility
Where focus lands when you press Tab depends on the computed CSS and DOM position after layout, and whether a focus outline is actually visible depends on computed styles too — both require a rendering engine stepping through real key presses, which a markup parser never does.
Screen-reader announcement behaviour
What a screen reader actually says depends on the browser's accessibility tree, the specific screen reader's own quirks (NVDA, JAWS and VoiceOver all differ), and live-region timing. None of that exists until real assistive technology is pointed at a live, rendered page.
Reading order
CSS can visually reorder content — flexbox, grid and absolute positioning can all put something on screen in a different place than it sits in the HTML — without changing the underlying document order at all. Spotting a mismatch means comparing visual layout against DOM order, which needs a renderer to produce the visual layout in the first place.
Cognitive load
Whether wording is confusing, navigation is consistent, or a task asks too much of working memory is a judgement call about clarity, not a rule that fires on a pattern in the markup. No automated check, ours included, can score how hard a page is to think through.
Content injected by JavaScript
We analyse the HTML your server sends on first response. Anything a script adds afterwards — a single-page app rendering its content client-side, a modal injected on click, a cookie banner built in React — never appears in that markup and never gets checked.
Anything that only exists once a browser renders it
Reflow at 400% zoom, hover and focus states, animation and motion, viewport-dependent layout shifts — all of these only exist after a browser has laid out, styled and painted the page. We never take that step, so we never see what only exists on the other side of it.
How much of WCAG this actually covers
Sources disagree on the exact number, but nobody credible claims automation covers most of WCAG. Karl Groves, who has spent longer measuring this than almost anyone, put it precisely: an automated tool "can definitively test for approximately 25–29% of best practices for WCAG 2.0" and "cannot test for approximately 40%" — the rest falls into a grey zone that needs a human judgement call either way. karlgroves.com/automated-lies-with-one-line-of-code
Different tools and researchers land on different figures because they're measuring different rule sets against different versions of WCAG, but roughly a third machine-detectable is the defensible, honest framing — not a round "half" or "most." We didn't build 16 rule checks plus a vision-model alt text audit because that gets you to 100%. It doesn't. It gets you further than reading HTML alone, and it's honest about the rest.
How the score is calculated
Every page starts at 100. For each rule check that fails, we count how many times it fails on that page, capped at 5 instances so one repeated issue — say, 40 images missing alt text — doesn't drown out everything else on the page. That capped count is multiplied by the check's severity weight: critical is worth 10 points, serious 5, moderate 2, minor 1. All of those deductions are summed and subtracted from 100, floored at zero. A site's overall score is the average of its page scores.
So a page with one critical issue (an image missing alt, capped at one instance for this example) loses 10 points and scores 90. A page with five instances of a serious issue loses 25 points and scores 75.
Say this plainly: the score is a prioritisation aid, not a compliance measure. It tells you where to spend an hour first. It cannot tell you whether a site meets WCAG, the EAA, the ADA or any other legal standard — no automated score can, because roughly two-thirds of what those standards require isn't something a machine can check at all.
See it run against a real page
Run the free scan against your own site and read the report against this page side by side — every issue it finds cites the check and the WCAG criterion above.
Scan my site — free