-
-
Paste any URL, or press Ctrl+V anywhere on the page, and the check starts.
-
Our demo page: 10 problems found, 10 fixed and proven by a second check, 0 new problems.
-
Every fix says what changed and where the clue came from, with its WCAG criterion and severity.
-
What a screen reader hears before and after. Changed lines are highlighted: "textbox" becomes "destination city, textbox".
-
The page looks the same after fixing. Only what assistive technology reads has changed.
-
Ship it today: one script with only the proven fixes, added with one line of code.
-
A real site, Hacker News: 246 problems found, 245 fixed and proven, 0 new problems.
Inspiration
The WebAIM Million 2026 checked the home pages of the top million websites and found 56.1 accessibility errors per page on average. More than half have images a blind person can't hear about, and 84% have text too faint to read. Checkers that list these problems already exist, and the page stays broken. Overlay widgets that promise to fix them are criticised by blind users for guessing and fighting their screen readers. We wanted the Ctrl+V of accessibility: paste a page, get it back usable, with proof.
What it does
- Check, fix, re-check. Paste an address (or press Ctrl+V anywhere on our page). Ctrl+A11y opens it in a real browser, runs axe-core, the standard accessibility checker, fixes what it can, and runs the same check again. A fix counts only if the same rule no longer flags the same element.
- Fixes the most common failures found by the WebAIM Million: low contrast text, missing image descriptions, missing form labels, empty links, empty buttons, missing page language, plus page titles, landmarks, tab order, invalid ARIA roles and links that rely on colour. Content outside every landmark that has its own heading becomes a section screen-reader users can jump to.
- Says where every fix came from, in plain language: "Name added: Search, from its icon class", "Description added: Goa from Rs 2,999, from the text inside the image". When there is no honest clue, it says so and leaves it for a person. An optional vision AI model can describe images that have no clue at all.
- Never leaves a page worse. If the re-check finds any new problem, the engine undoes fixes one kind at a time until no new problem remains, and reports what it rolled back.
- Ship it today. Site owners download one script with only the proven fixes and add one line to their page.
- Fix pages as you browse. People who use screen readers add one bookmark; on any hard page it applies the proven fixes and announces how many it applied.
- Works on real, messy sites: strict security policies, carousels that change on every load, content that appears seconds late. A fresh unfixed copy is checked the same way, so the page's own changes are never blamed on a fix.
- For teams: WCAG criterion and severity on every problem, a printable report, a check of 5 more pages of the same site, before/after screenshots, and a CI mode that fails the build when too many problems remain.
How we built it
Python, Playwright and Chromium for a real browser; axe-core 4.10.2 for checking; FastAPI for the app; plain HTML, CSS and JavaScript for the interface; Docker for hosting; an optional vision AI model for images with no clue on the page. The fixers are plain code, so the same page always gets the same fix. Tests run on every push in GitHub Actions: three planted demo pages, the fix script, the safety net (by sabotaging a fixer on purpose), the server's safety rules, and the Docker image itself. A benchmark script writes every number we show into CSV files. Even the demo video is generated by code from the real app.
Results
- Demo page: 10 of 10 problems fixed and proven, 0 new problems, no AI model.
- 6 real public pages: 533 problems before, 93 after. 401 fixes proven, 39 more resolved by related fixes, 0 failed re-checks, 0 new problems. Python.org: 112 to 2. Hacker News: 246 to 1.
- 7 Indian sites (MyGov, myScheme, DigiLocker, The Hindu, IIT Bombay, VTU, Flipkart): 563 problems before, 315 after, 244 fixes proven, 0 failed re-checks, 0 new problems. **myScheme, the government's scheme finder: 29 to 0. The Hindu: 123 to 28. DigiLocker: 55 to 15.
- The fix script alone, on fresh untouched copies, reproduces exactly what the engine measured.
- Our own page: 0 problems on our own check, checked in CI on every push.
- Honest gaps: some government sites block automated browsers, so we report them as not scored. Heading order still needs a person.
Challenges we ran into
- Making "fixed" mean something: we re-run the checker and match each fix to the exact element instead of trusting our own fix.
- A fix can make a page worse: our first landmark fixer marked a heading as the main area. We built the automatic rollback, then tested it by sabotaging a fixer on purpose.
- Pages that change on every load: our first safety net undid good fixes on MyGov because its carousel looked "new" on every reload. We now compare against a fresh unfixed copy, timed the same way.
- Indian mobile networks: on NAT64 networks every site looked like a private address, so our security check refused them. We now check the real address inside.
- Not guessing: every name comes from a real clue on the page, and we show which one.
Accomplishments that we're proud of
- Not an overlay: no widget, no toolbar, no tracking, only the same fixes a developer would make.
- Zero new problems and zero failed re-checks across every page we measured.
- A blind user can fix a page for themselves with one bookmark, and hear that it worked.
- Our own page passes our own check.
What we learned
- A fix you can't prove isn't a fix. Separating a page's own changes from ours taught us more than any passing test.
- Less ARIA is often the accessible answer. Removing a broken
role="tree"fixed more problems than adding anything. - Real sites are messy in ways demo pages never are, and each surprise became a test.
- Our own page had to pass first.
What's next
- Turn proven fixes into a pull request on the site's own source code.
- Whole-site crawls, PDFs, and pages behind a login.
- Image descriptions in the user's own language.