Ten million places on the web where a screen reader has nothing to say
We swept 275,292 pages across 30,541 sites and counted every element that reaches a screen reader with no accessible name. There were 10,390,627 of them. The useful part is what happened next: they collapse into 1,937 shapes, and 299 of those recur across twenty-five sites or more.
- 275,292pages swept
- 30,541sites
- 93country domains
- 10,390,627silent elements
- 1,937distinct shapes
The silence is not infinite variety
Every silent element was recorded as a shape: the tag, whether it wraps an icon or an image, how many children it has. Ten million of them are 1,937 shapes, and the top eight account for most of the web’s silence. The first one is an icon-only control — a button whose entire content is one svg.
| Shape | What it is | Elements | Sites |
|---|---|---|---|
svg|svg1|kids1 | An icon-only control: one svg inside and nothing else | 2,220,904 | 16,699 |
img|img1|kids0 | A bare image with no description | 1,581,894 | 21,643 |
div|img1|kids1 | A div wrapping a single image | 907,299 | 16,288 |
span|svg1|kids1 | A span wrapping a single icon | 756,779 | 9,438 |
div|svg1|kids1 | A div wrapping a single icon | 656,747 | 12,210 |
span|pseudo|kids0 | An icon drawn by CSS, with no element to name | 447,435 | 5,871 |
div|bg|kids0 | An image set as a CSS background | 436,423 | 12,899 |
a|press|img1|kids1 | A link that is only a picture | 245,371 | 8,786 |
All 1,937 are in crawl-by-shape.csv. This is the part worth arguing with: if the long tail matters more than we think, the file is where you would show it.
By country domain
Zone, not geolocation — a .de site may be hosted anywhere. Largest twelve; all 93 are in crawl-by-country.csv.
| Zone | Pages | Sites |
|---|---|---|
.de Germany | 15,737 | 1,634 |
.fr France | 13,579 | 1,466 |
.uk United Kingdom | 13,547 | 1,500 |
.jp Japan | 12,705 | 1,424 |
.it Italy | 12,315 | 1,324 |
.pl Poland | 11,694 | 1,254 |
.br Brazil | 10,927 | 1,258 |
.nl Netherlands | 10,813 | 1,102 |
.in India | 10,798 | 1,302 |
.au Australia | 10,058 | 1,064 |
.ca Canada | 7,832 | 844 |
.es Spain | 6,724 | 718 |
What the engine repaired, and what a person hears
A second and smaller corpus: 277,197 repairs the engine actually made on 4,791 sites (6,737 hosts), median 28 per site. Unlike the sweep, each line carries the name the engine produced — which is what makes the accuracy check below possible at all.
| Kind | Repairs | Share | What a person hears |
|---|---|---|---|
| Image with no description | 152,139 | 54.9% | The reader says “image”, and the person decides whether to care. |
| Button or link with no name | 81,334 | 29.3% | The reader says “button”. Thirteen of those in a row is a menu nobody can use. |
| Form field with no name | 43,724 | 15.8% | The reader says “edit”. Nothing says which box takes the card number. |
The third row is the smallest and the most expensive. A form field with no name means the customer reaches the payment step and hears “edit, edit, edit”, with nothing saying which box takes the card number. It sits behind the login, which is where a free scanner stops looking.
How often an automatic repair is wrong
Measured twice, at different scales. A random sample of 200 repairs (seed 20260911) was checked by hand against the original HTML:
| Correct — the name identifies the element | 155 | 77.5% 95% CI 72–83% |
|---|---|---|
| Harmless but useless — a filename, a class name | 38 | 19.0% |
| Wrong — the name states something false | 2 | 1.0% |
| Not verifiable from the recorded data | 5 | 2.5% |
Both wrong ones are named here, because they are a class and not an accident:
- A transparent 1×1 tracking pixel was given a name, so a reader announces an image that is not there.
- A carousel control was named “Next slide” while the arrow inside it points left.
The engine names things that should be hidden, and it trusts nearby text more than the icon itself. Both are fixable; neither was known before the sample was judged.
Separately, during the sweep a model checked 27,856 elements on 7,341 pages against the engine’s own verdict: 800 false alarms (2.9%) and 7,556 misses. Larger than the hand sample and weaker evidence — a model checking a model — which is why it is reported second and not instead.
What these numbers cannot mean
There is no denominator anywhere on this page
The crawl recorded only silent elements; the repair corpus recorded only misses. Neither counted what was already correct, so no share of the web follows from either. “10,390,627 silent places across 30,541 sites” is a fact. “X% of the web is broken” is not, and cannot be derived from this.
A site with no finding is not a clean site
It may simply not have been reached that deep. Silence here means silence, not health.
The two corpora are not the same measurement
The crawl contains no repair and no label, so nothing in it can be judged right or wrong. The accuracy figures below apply only to the repair corpus, which is smaller and separate.
The accuracy figure is from 200 hand-judged repairs
Random, with a published seed, and its composition matches the corpus — but it is still 200 out of 277,197. The judge comparison alongside it is larger and was made by a model, not a person.
The site list is a crawl queue, not a sample of the web
It is weighted towards whatever that queue happened to hold. The country table says something about our sweep, not about Germany or Japan.
Country means the domain zone, never geolocation
A .de site may be hosted anywhere and sell anywhere. We do not pretend to know where.
If you have seen different numbers from us
An internal summary dated 7 August 2026 says 29,241 sites, 286,252 pages and 10,126,677 silent places. It ran on a snapshot taken while the sweep was still arriving and cannot be reproduced from the files here, so this page carries what count.py prints instead. The shape counts agree almost exactly — 1,937 shapes against 1,936, and 299 shapes on 25+ sites against 300 — which is how we know both are counting the same thing. Letters we sent earlier quote 6,737 sites for the repair corpus: that is the same data counted in hosts rather than registrable domains.
The files
| crawl-by-shape.csv | all 1,937 shapes, with how many silent elements and how many sites each accounts for |
|---|---|
| crawl-by-country.csv | pages and sites swept, by domain zone |
| repairs-by-site.csv | every site the engine repaired, and how many repairs it needed |
| repairs-by-kind.csv | the three kinds of repair and their shares |
| sample200.txt | the 200 sampled repairs as they were judged |
| verdicts.json | the verdict for each of the 200, by number |
| summary.json | every headline figure on this page |
| count.py | the script that produces all of the above from the raw corpora |
The sweep needs our engine. The method behind it does not: open a site, press Tab, and listen. Chromium hands a screen reader its accessibility tree, and DevTools shows you the same tree under the Accessibility pane. Twenty minutes with NVDA or VoiceOver reproduces the idea on any site you like.
Disclosure
The engine is ours. This is not independent research, it is the work of an interested party — which is exactly why the method, the limits, the error rate and the raw files are on this page rather than summarised in a sentence. If a number here is wrong, what is above is enough to prove it.
What we do with this: Qiksy Access audits a live store, through the login, and the audit itself costs nothing.