Blog

A site everyone can use is not an optional extra

Accessibility covers far more people than screen reader users, and when it fails it fails so quietly that nobody tells you. What it means, why it matters, and what checking our own site turned up.

Published

A diagram of four routes — keyboard, screen reader, zoom and single-thumb touch — all arriving at the same page, over a photograph of a long indoor walkway

Somebody wants to apply for a job with us. They use a keyboard and no mouse. They open the site on a phone, press the menu button, tab down the list to the last item, and press Tab once more.

Focus leaves the menu and lands in the page behind it — the page under a navy scrim, scroll-locked, and completely invisible to them. They have no idea where they now are. All they know is that pressing Tab stopped doing anything they could follow.

We fixed that this morning. It is not a bug anybody finds by looking at a screen.

Before the account of what we checked, though, three things are worth setting
out: what accessibility actually means, why it matters more than most teams
assume, and what we think about it. Skip those and the fixes below are just a
list of tasks to read past.

What accessibility actually means

Say the word and most people picture one thing: somebody who cannot see the
screen, listening to it through a screen reader. That is genuinely part of it,
and a smaller part than people think.

What it actually asks is whether somebody can use the thing without having the
same body, eyes, hands or equipment as the people who built it.

Run through who that covers. Somebody working from the keyboard alone because a
tremor makes a mouse unusable. Somebody at 200% zoom because of low vision.
Somebody with increased contrast switched on permanently. Somebody who turns off
animation because motion genuinely makes them ill. Somebody listening rather
than reading. Somebody who needs clear headings and order because long unbroken
text loses them.

And the group people forget is the largest one: those with nothing permanent at
all.

A broken arm makes a mouse awkward for two months. Sunlight on a screen makes
pale grey on white unreadable. A child on one arm leaves one thumb for the
phone. A slow connection leaves the scripts half-loaded. Every one of those
people meets exactly the barriers that somebody with a permanent impairment
meets. The difference is that theirs clears up in a few weeks.

Put plainly: accessibility is not a feature for a small group at the edge. It is
how well the work holds up when conditions are not the ones imagined by the
person who built it.

Why it matters more than teams assume

First, nobody arrives to admire a website. They arrive to do something — apply
for a job, ask for a quote, find a phone number, read the terms before deciding.
When that fails, what is lost is not their good impression. It is the thing they
came to do.

Second, and worse: it fails silently.

A customer who presses a button and gets nothing will phone and complain.
Somebody who tabs out of a menu into the page behind it will not tell anyone.
They close the tab and go elsewhere. From our side the traffic looks ordinary,
no error is raised, and nothing lands in a log. Faults of this kind survive for
years without a single person on the team knowing they exist.

Third, the part that gets left out of the argument: nearly all of this work
comes back as quality for everybody else. Correct heading order serves screen
readers and Google alike. Image descriptions serve people who cannot see them
and people whose connection never loaded them. A label genuinely tied to its
field means clicking the label puts the cursor in the field, which helps
everyone. Sufficient contrast helps anybody reading outdoors.

There is almost nothing here that helps one group at another's expense — which
is unlike nearly every other decision in design.

What we think about it

Some people will tell you a company website does not need any of this, because
those visitors were never going to show up anyway.

We disagree, strongly.

First, it is an argument that proves itself. If the site cannot be used, those
visitors do not show up, and the traffic confirms the decision — even though the
traffic is a result of the decision. That is not measuring demand. It is
measuring a door we locked ourselves.

Second, at GIPSIC we hold that everyone is equal. What we build should be usable
by everyone, not only by people who happen to have the bodies and the equipment
of the people who built it. That is not a feature to add later if time allows.
It is part of what "finished" means.

Third, thought about from the start it costs almost nothing. What is expensive
is going back to rebuild something already built wrong — and not knowing where
it is wrong.

Which is the reason we went and checked.

A debt we wrote down ourselves

When we closed our series about building this site on 31 August, we said plainly that we had not tested it with a screen reader in any systematic way, and had not tested it with anybody who uses one daily.

The section ended: we are writing it here so it is a visible debt rather than a silent gap.

It stayed there until this week, when we finally did the work. This is the record of it — the parts we had got right without ever proving it, and the parts we thought we had got right and had not.

How we checked

Not by reading our own source and assuming. We opened the live pages on the live server and asked each one a set of questions.

Does the heading order skip a level. How many level-one headings are on this page. Does every link and button have a name a screen reader can read out. Does every image carry a description. Is every field tied to its own label. And where does pressing Tab actually take you.

Tools answer those questions. Reading the answers takes a person, because several things a tool marks as passing pass for the wrong reason — and at least one thing it marked as failing turned out to be our own measurement being wrong. More on that below.

What passed, and we only now know it passed

No page skips a heading level. Every page has exactly one level-one heading. Not one link or button is missing a name. Not one image is missing a description.

When the mobile menu is closed, all twenty-three links inside it are genuinely out of the tab order — not merely hidden from view. That distinction matters: a menu hidden only visually leaves twenty-three invisible stops that a keyboard visitor has to pass through on every page of the site.

The language switcher announces itself correctly as a menu of exclusive choices, and says which language is currently set. The reading-progress bar on articles is hidden from assistive technology, because "you are forty percent through" is not a sentence anybody needs read aloud.

The spam trap that could have swallowed applications

This one passed too, but it deserves its own section, because getting it wrong fails in total silence.

Our contact and application forms carry a field that people never see and bots fill in anyway. If it arrives with anything in it, the submission is dropped and the sender is told it went through — telling a bot it was caught only teaches it what to change.

Now follow that through. If the field were hidden by position alone, a screen reader would still find it and still offer "Company website" to be filled in. Somebody who cannot see it would fill it in honestly, and every application they ever sent us would be discarded, each one confirmed as delivered.

They would never know. Neither would we, because from our side nothing looks wrong at all.

This site hides that field from assistive technology as well as from view, and takes it out of the tab order. That is the right way round. We had simply never confirmed it until now.

The four that did not pass

One: a menu that called itself modal and only half meant it. While open, our mobile drawer declares that the page behind it is not there. Screen readers believe that. Keyboards do not, because nothing was actually stopping them: thirty-eight focusable things outside the drawer remained perfectly tabbable. We had declared something and not made it true.

Opening the drawer now moves focus into it, Tab cycles at both ends, and closing it returns focus to the button that opened it. That last part matters most — closing the menu used to drop focus at the top of the document, so anybody who had worked their way down the page started again from the beginning.

Two: required fields marked with an asterisk and nothing else. The label reads "Name" with a blue asterisk after it. Anybody who can see it understands immediately. Anybody listening hears "Name".

Put another way: the one group who cannot see the asterisk was the one group we had not told. Required fields now say so.

Three: hint text that belonged to nothing. Under the file field it says "PDF or Word, under 5 MB". That text is genuinely on the page — but as far as the browser was concerned it was just some words nearby, not a description of any particular field. Tab into the field and you heard its name, then had to guess what it would accept.

Four: focus lost on a successful send. Submitting replaces the whole form with a thank-you panel, which removes the button the visitor just pressed, which sends focus back to the start of the document. A keyboard visitor is returned to the top of the page with no idea whether anything was sent. The confirmation panel now takes focus itself, so the first thing read out after sending is the confirmation.

Fix the cause, not each field

Two and three look like small jobs. Add the missing attribute to every field and you are done.

Fixed that way, they come back with the next form somebody adds, when they forget — and they will forget, because none of it is visible while clicking around with a mouse.

So we fixed the field component instead. It is already the thing that draws the label and the asterisk. It already knows whether a field is required and whether a hint sits underneath it. Both facts now travel down to the control on their own.

New forms cannot ship without them. A fixed bug is one bug gone; a fixed cause is a category of bugs that never happens again.

What we checked and still cannot answer

A contrast checker we wrote reported twenty-six failures, all of them text on our navy sections.

Then we read the numbers it produced: white text on a white background. That is not what is on the page. Our checker could not find the real background, because that background is a gradient rather than a flat colour, so it walked up the page until it hit white and used that instead.

That is our instrument being wrong, not the site. Until we teach it to read gradients, we cannot say whether those twenty-six pass or fail.

We are writing that down for the same reason as before. Reporting a clean audit while one question remains unanswered is not a clean audit, it is a bad report.

And the original gap stands: we still have not sat and listened to a screen reader work through this site end to end, and still have not tested with somebody who uses one every day — the only test that shows whether the order of the content makes sense.

All four took less than half a day

Back to the claim that this can wait. All four — finding them, fixing them, and
getting the fixes onto the live site — took less than half a day between them.

The cost was never the problem. Not knowing was, and not knowing does not clear
up on its own while you wait.

Try it on your own product

You need no tools at all. Just your keyboard.

Open your product's main page and take your hand off the mouse. Press Tab all the way through. Three questions: can you see where you are at every step; is there anywhere you can get into and not out of, or that drops you somewhere invisible; and when you open a dialog and close it, where does focus end up.

Ten minutes, and it finds more than several automated scanners put together — because it measures the thing being used, not the presence of code.

If you would like us to look at a system or a site you are building, get in touch.

About the author

Portrait of Film

Film — Wisit. A businessman who still does his own BA work more often than he probably should, and writes a fair bit of code, front and back. Runs two or three small businesses. Follows technology and business obsessively, in Thailand and everywhere else. Off the clock: physics, astronomy, DIY, and anything to do with networks. Music always on, though he cannot sing. Plays instruments anyway, badly. Plays a lot of sport, racket sports above all. Not much of a traveller by himself, but happy to take Mint anywhere in the world. A man who fears — sorry, loves — his wife. One flaw: he barely touches video games.

Written with Claude Opus 5