Skip to content

The measurement

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.

Generated 14 September 2026. The engine is ours, see Disclosure. Every figure here is printed by count.py from the files below. The sweep is still running: what it has reached so far.

  • 275,292pages swept
  • 30,541sites
  • 93country domains
  • 10,390,627silent elements
  • 1,937distinct shapes

Live from crawl.qiksy.app/live.json

The sweep has not stopped

Everything below is one roll-up, printed on a named date and frozen there so the files and the page agree. The crawl itself is still going. Three lanes run continuously on a machine in the lab, each finishing a batch and starting the next every twenty-five to forty-five minutes; the totals here are re-counted every hour by the same script and read live from this page.

sites so far
30,541
pages so far
275,292
silent elements
10,390,627
country domains
93

The roll-up has not been refreshed for some hours, so treat the live figures as historical until it catches up. The tables below are unaffected.

  • w1started 47 min agorunning
  • w2started 47 min agorunning
  • w3started 47 min agorunning

In the current queue: 3,274 sites waiting, 9,416 finished. A queue, not a remaining total: it is the list we happen to be working through, and it is added to. Nothing here divides into anything.

rolled up 140 h ago · re-counted hourly · this page refetches every 10 minutes

Cannot mean These are the same counts as the tables below, taken later, not a different measurement, and the difference between two roll-ups is not growth we have measured. There is still no denominator: this counts silent elements, never the elements that were already correct.

Exhibit 1 from crawl-by-shape.csv

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.

ShapeWhat it isElementsSites
svg|svg1|kids1An icon-only control: one svg inside and nothing else2,220,90416,699
img|img1|kids0A bare image with no description1,581,89421,643
div|img1|kids1A div wrapping a single image907,29916,288
span|svg1|kids1A span wrapping a single icon756,7799,438
div|svg1|kids1A div wrapping a single icon656,74712,210
span|pseudo|kids0An icon drawn by CSS, with no element to name447,4355,871
div|bg|kids0An image set as a CSS background436,42312,899
a|press|img1|kids1A link that is only a picture245,3718,786

What this says

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.

Exhibit 2 from crawl-by-country.csv

By country domain

Largest twelve; all 93 are in crawl-by-country.csv.

ZonePagesSites
.de Germany15,7371,634
.fr France13,5791,466
.uk United Kingdom13,5471,500
.jp Japan12,7051,424
.it Italy12,3151,324
.pl Poland11,6941,254
.br Brazil10,9271,258
.nl Netherlands10,8131,102
.in India10,7981,302
.au Australia10,0581,064
.ca Canada7,832844
.es Spain6,724718

Cannot mean Zone, not geolocation. A .de site may be hosted anywhere and sell anywhere. This table says something about our sweep, not about Germany or Japan.

Exhibit 3 from crawl-by-zone.csv

How many silent places a reader meets on one page

Pages swept says how far we went, not what it is like to read there. This does: for every zone deep enough to speak about, meaning at least 1,500 pages across at least 100 sites, how many elements with no accessible name sit on an average page, on the median page, and how often a page had none at all. Zones below that threshold are not listed rather than listed badly: with a handful of sites the average describes those sites, not a country.

ZonePer pageMedian pagePages with nonePagesSites
.by Belarus55.6255.1%1,895196
.ru Russia50.0206.6%10,3141,227
.fi Finland49.1198.2%3,506379
.se Sweden48.5157.6%5,417555
.sg Singapore47.7208.4%1,758184
.pt Portugal43.1168.8%2,694288
.no Norway42.9155.7%3,741362
.hu Hungary42.8179.5%4,011437
.dk Denmark42.3165.7%3,239340
.fr France41.8168.4%13,5791,466
.tr Türkiye41.0145.8%4,377471
.pe Peru40.6209.1%1,528161
.ua Ukraine40.6177.7%5,338613
.ch Switzerland40.5168.6%4,451498
.mx Mexico40.2159.9%3,335363
.de Germany39.9159.7%15,7371,634
.cl Chile39.7178.3%2,886327
.my Malaysia39.01310.8%1,733225
.cz Czechia38.51410.9%6,039691
.pl Poland37.7158.6%11,6941,254
.gr Greece37.3197.1%3,901452
.ro Romania36.81410.4%4,785502
.nl Netherlands36.7168.1%10,8131,102
.be Belgium36.41411.5%3,846438
.it Italy35.8167.8%12,3151,324
.at Austria35.7139.6%4,256452
.cn China35.4155.6%4,746750
.br Brazil35.11410.2%10,9271,258
.in India35.01114.2%10,7981,302
.au Australia34.81310.1%10,0581,064
.za South Africa34.51310.4%3,173396
.ie Ireland33.41111.2%2,528271
.kz Kazakhstan33.11510.7%2,110255
.es Spain32.9139.5%6,724718
.ar Argentina32.6157.4%3,173351
.ca Canada32.41012.1%7,832844
.nz New Zealand31.31113.7%2,041223
.ph Philippines30.91410.1%1,667215
.uk United Kingdom30.2129.5%13,5471,500
.jp Japan28.3819.0%12,7051,424
.tw Taiwan26.4818.3%3,138430

What this says

The spread between the worst zone and the best is about twofold, and the best one still leaves eight unnamed places on the median page with only 19 pages in 100 carrying none. There is no clean country here.

Cannot mean This is not a league table: a zone is a queue we crawled, not a random sample of that country’s web.

Exhibit 4 from repairs-by-kind.csv

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.

KindRepairsShareWhat a person hears
Image with no description152,13954.9%The reader says “image”, and the person decides whether to care.
Button or link with no name81,33429.3%The reader says “button”. Thirteen of those in a row is a menu nobody can use.
Form field with no name43,72415.8%The reader says “edit”. Nothing says which box takes the card number.

What this says

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.

Exhibit 5 from sample200.txt · verdicts.json

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.

JudgementRepairsShare
Correct: the name identifies the element15577.5% 95% CI 72–83%
Harmless but useless: a filename, a class name3819.0%
Wrong: the name states something false21.0%
Not verifiable from the recorded data52.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.

What this says

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.

Cannot mean These figures apply to the repair corpus only. Nothing in the sweep was verified this way, and nothing in it can be: the sweep records no repair and no name, so it holds nothing to judge.

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
crawl-by-zone.csv
silent places per page, median page and share of pages with none, for the 41 zones deep enough to speak about
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.

Qiksy Access. The measurement. 14 September 2026. https://qiksy.app/access/data/