For six years the web was slowly getting more accessible. In 2026 it stopped.
Every February, WebAIM runs an automated accessibility check on the home pages of the top one million websites. The 2026 run found detectable WCAG 2 failures on 95.9% of them, up from 94.8% a year earlier. The average page now has 56.1 detectable errors, up 10.1% from 51.
While writing my thesis on accessibility tooling for React, I went through the WebAIM reports from 2023 to 2025. When the 2026 report came out, I added it to the dataset. Here's what four years of data say, and what they mean if you ship React.
Four years in one table
| Metric | 2023 | 2024 | 2025 | 2026 |
|---|---|---|---|---|
| Home pages with detected WCAG failures | 96.3% | 95.9% | 94.8% | 95.9% |
| Average detected errors per page | 50.0 | 56.8 | 51.0 | 56.1 |
| Average elements per home page | 1,050 | 1,173 | 1,257 | 1,437 |
Two things stand out.
First, the failure rate barely moves. In four years it went from 96.3% to 95.9%. Almost every popular site still fails an automated check, and automated checks only find part of the real problems. WebAIM says this directly: the real level of conformance is lower than these numbers suggest.
Second, pages keep getting heavier. The average home page grew from 1,050 to 1,437 elements, +37% in three years. More elements means more places to get something wrong, and the error count follows.
The same six bugs, every year
About 96% of all detected errors come from just six types. Here's how often each one appeared on home pages:
| Failure | 2023 | 2024 | 2025 | 2026 |
|---|---|---|---|---|
| Low contrast text | 83.6% | 81.0% | 79.1% | 83.9% |
| Missing image alt text | 58.2% | 54.5% | 55.5% | 53.1% |
| Missing form input labels | 45.9% | 48.6% | 48.2% | 51.0% |
| Empty links | 50.1% | 44.6% | 45.4% | 46.3% |
| Empty buttons | 27.5% | 28.2% | 29.6% | 30.6% |
| Missing document language | 18.6% | 17.1% | 15.8% | 13.5% |
None of these is hard. None needs a specialist. They're the kind of bugs a linter or a single axe-core run catches in seconds.
The interesting rows are the ones that move:
- Missing language is the only steady win. It dropped from 18.6% to 13.5%. My guess: framework starters and templates now ship with
<html lang>set by default. One default in a template fixed it for thousands of sites. - Empty buttons go up every year. 27.5% to 30.6%. That's the icon button: a
<button>with an SVG inside and no text oraria-label. Component libraries made icon buttons cheap to add, and nobody made them cheap to name. - Missing labels went up too. 45.9% to 51%. Placeholder-only inputs and custom selects are still everywhere. The lesson from the
langrow works the other way as well. Fix a bug in a shared default, and it's fixed everywhere. Ship a bug in a shared component, and it's broken everywhere.
Is React the problem?
My thesis originally assumed that client-side frameworks make accessibility worse. The data didn't agree.
| Framework | Avg errors, 2025 | vs average | Avg errors, 2026 | vs average |
|---|---|---|---|---|
| Next.js | 38.6 | −24.2% | 40.9 | −27.1% |
| React | 42.4 | −16.8% | 43.5 | −22.5% |
| Nuxt.js | 45.2 | −11.2% | 54.7 | −2.6% |
| Vue.js | 58.7 | +15.3% | 64.6 | +15.1% |
React and Next.js pages had fewer detected errors than average in both years. In 2026 Astro had the fewest of all, 9.0 per page, 84% below average.
This is correlation, not cause. Sites built with React may simply have bigger teams and more QA. But it kills the easy excuse: "we use an SPA framework, so accessibility is hard" doesn't match the numbers.
What does correlate with more errors is complexity and the libraries piled on top. WebAIM's 2026 conclusion links the increase to heavier reliance on third-party frameworks and libraries, and to AI-assisted "vibe coding".
The ARIA paradox
ARIA is supposed to fix accessibility. On real pages it often goes the other way:
- 82.7% of home pages use ARIA (not counting landmark roles), up from 79.4%.
- The average page has over 133 ARIA attributes, up 27% in one year.
- Pages with ARIA averaged 59.1 errors. Pages without it averaged 42. Again, more complex pages use more ARIA, so ARIA isn't necessarily the cause. But it's a good reminder of the first rule of ARIA: if a native element does the job, use it. A
<button>gets focus, keyboard support and a role for free. A<div role="button">has to rebuild all of that by hand, and usually doesn't.
Why this is now a business problem
For a long time, accessibility lived in the "nice to have" column. That's changing.
- The audience is big. The WHO estimates 1.3 billion people, about 16% of the world, live with significant disability.
- Lawsuits are routine in the US. UsableNet counted 5,114 digital accessibility lawsuits in 2025. 70% targeted e-commerce. About 45% of federal suits hit companies that had already been sued before.
- The EU has a law now. The European Accessibility Act has applied since June 28, 2025. It covers e-commerce, consumer banking, transport ticketing, telecoms and e-books, and points to EN 301 549, which is built on WCAG.
- Overlays are not a fix. In April 2025 the US FTC finalized an order making accessiBe pay $1 million over claims that its AI widget makes any site compliant. A script on top of broken markup doesn't repair the markup. ## What this means for a React team
The six common failures map almost one to one onto checks you can automate today:
| Failure | Lint (eslint-plugin-jsx-a11y) | Runtime (axe-core) |
|---|---|---|
| Low contrast | not visible in JSX | color-contrast |
| Missing alt | alt-text | image-alt |
| Missing labels | label-has-associated-control | label |
| Empty links | anchor-has-content | link-name |
| Empty buttons | control-has-associated-label | button-name |
| Missing lang | html-has-lang | html-has-lang |
What I'd do, in this order:
- Turn on the lint rules. They catch alt, label and empty-link bugs while you type.
control-has-associated-labelis off even in the recommended config, and that's the one that catches empty buttons, so check what your preset really enables. - Run axe-core in development and in CI. Contrast can't be linted, because the color depends on CSS at runtime. A runtime check is the only automated way to catch it.
- Fix the shared components first. Your
IconButton,InputandLinkcomponents are where the empty-button and missing-label bugs breed. One fix there is a fix on every page. - Keep contrast in your design tokens. Check token pairs once, and new screens can't drift below 4.5:1 by accident.
- Still test by hand. Tab through the page, open a screen reader. Automation finds the boring 96%, not the rest. I wrote about how I built this kind of pipeline (lint, dev overlay and CI audit on one rule catalog) in my previous post. Next week: what happened when we ran it on a real production project, and how 427 violations became zero in three weeks.
Which of the six do you see most in your codebase? My bet is empty buttons.

