Rung 3

Accessibility

Rung three: the page reached the device. Can it reach the person?

Where this rung sits

The page is up and it loaded. Now it meets a human — who may be blind, low-vision, colorblind, deaf, unable to use a mouse, prone to motion sickness, or simply sixty-five with ordinary eyes on a bright day. Accessibility asks: can this person perceive what the page presents, and operate what it offers?

It comes before internationalization on the ladder: a blind reader in Madrid never reaches the moment of struggling with your English if her screen reader finds only unlabeled <div> soup. And it stops short of usability: whether the labeled, reachable, readable checkout actually makes sense as a task is the next rung. Here we care about the mechanics of perception and operation — the interface between your markup and a person's senses and hands.

The load-bearing fact: assistive technology does not read your pixels. Screen readers, voice control, and switch devices consume the accessibility tree, which the browser builds from your markup's semantics. Every element contributes a role (what it is), a name (what it's called), and a state (what it's doing). Semantic HTML fills all three in automatically. A <div onclick> contributes nothing: no role, no name, no keyboard behavior. It is a rumor of a button that only sighted mouse users can hear.

The failure catalog, by ability

Blind users: structure and names

A screen reader user skims by headings, jumps by landmarks, and pulls up lists of links and form controls. That workflow requires:

  • Landmarks and headings. <header>, <nav>, <main>, <footer>, and a real heading outline give the page a skimmable shape. A page of styled <div>s has no shape; it can only be read linearly, start to finish, every visit.
  • Text alternatives. Informative images need alt that carries the same information; decorative images need alt="" so they are skipped. A filename as alt text is worse than nothing — it spends the listener's time saying nothing.
  • Accessible names. Every control announces as something: "Add to cart, button" or, done wrong, "clickable." Real elements plus visible labels (<label for>) provide names for free; icon-only controls need one supplied (aria-label).
  • ARIA misuse. aria-hidden="true" removes an element and everything inside it from the accessibility tree while leaving it fully visible. Pasted onto a nav wrapper, it makes your menu cease to exist for exactly the users who most need its structure — while every automated screenshot looks perfect.

Low-vision users: size, zoom, and contrast

  • Respect their text size. Users set a default font size in browser settings; rem-based sizing scales with it, hard-coded px overrules it.
  • Never block zoom. user-scalable=no and maximum-scale=1 disable pinch zoom. Some browsers now ignore the setting out of mercy; don't rely on their mercy. Layouts should survive 400% zoom by reflowing, not by demanding horizontal scrolling.
  • Contrast. WCAG asks 4.5:1 for normal text, 3:1 for large text and UI components. Light gray on white passes the squint test on a designer's monitor and fails on a phone in sunlight, a cheap panel, or older eyes — which will one day include yours.

Colorblind users: color as the only channel

Roughly 1 in 12 men and 1 in 200 women have a color vision deficiency. A green dot for in-stock and a red dot for sold-out is, for them, two identical dots. Color may reinforce meaning; it may never be the only carrier. Pair it with text or a distinct shape.

Motor-impaired and keyboard users: operation

  • Everything operable by keyboard. Real <button> and <a href> elements are focusable and respond to Enter and Space natively. Clickable divs are unreachable by Tab — for keyboard-only users the control does not exist.
  • Visible focus. outline: none blindfolds keyboard navigation. Style focus, never remove it; :focus-visible shows the ring for keyboard use without flashing it at mouse clicks.
  • Sane focus order. Focus follows DOM order. Positive tabindex values scramble it into a treasure hunt. The rule: tabindex="0" rarely, tabindex="-1" occasionally, positive values never.
  • A skip link. Mouse users jump straight to content; keyboard users must Tab through every header link on every page unless the first tab stop offers "Skip to content."
  • Target size. WCAG 2.2 sets a 24×24 CSS pixel minimum; Apple and Google guidelines say 44–48. Tremor, arthritis, gloves, or a moving bus make an 18px hit area a wall.

Vestibular disorders: motion

Parallax, pulsing badges, and endless tickers can cause genuine dizziness and nausea. The operating system exposes the user's request; honoring it is one media query:

@media (prefers-reduced-motion: no-preference) {
        .sale-badge { animation: pulse 2s infinite alternate; }
      }

Note the direction: animation is the opt-in for those who haven't asked for calm, not something to claw back. The same pattern serves prefers-color-scheme and prefers-contrast — user preferences the platform hands you for free, if you listen.

Deaf and hard-of-hearing users: sound

Audio and video carry meaning that needs a second channel: captions for video, transcripts for audio, and never sound-only notifications. (Our demo store has no media; when yours does, this rung applies with full force — and captions, like alt text, are content work, not markup work.)

Cognitive load: the mechanical part

Persistent labels (a placeholder vanishes the moment you type), consistent placement, predictable focus behavior, and errors identified in text next to the field. Where this shades into whether the task makes sense — naming, flow, mental models — you have climbed to the usability rung. Hold that line: this lesson is about perception and operation.

The checklist

Perceive-and-operate review
CheckWho is locked out if skipped
Landmarks, one <h1>, logical heading outline, descriptive <title>Screen reader users lose the page's shape entirely
Informative alt; alt="" for decorationBlind users get silence or filenames
Real <button>/<a>; no clickable divs; no ARIA where HTML sufficesKeyboard and screen reader users can't reach or identify controls
Visible :focus-visible style; no outline: none; no positive tabindex; skip linkKeyboard users navigate blindfolded through a scrambled maze
Visible, persistent <label> on every fieldScreen reader and cognitive-load users face anonymous inputs
4.5:1 text contrast, 3:1 for large text and controlsLow-vision users, and everyone in sunlight
Color never the only carrier of meaning1 in 12 men can't tell your red from your green
rem sizing; zoom never blocked; reflow at high zoomLow-vision users denied their own settings
Targets 24px minimum, 44px preferredAnyone whose hands shake, today or eventually
Animation gated behind prefers-reduced-motionVestibular-disorder users pay in nausea
Captions and transcripts for mediaDeaf and hard-of-hearing users lose the content

The exercise: change bodies

Open the inaccessible store and the accessible store. They look nearly identical. Now borrow some other abilities:

  1. Unplug your mouse. Tab through the broken store. Where are you? (Focus is invisible.) What order are you moving in? (Scrambled.) Now try to add the fleece to the cart. You can't — the button is a div. Repeat on the fixed store: skip link first, visible ring, sane order, working buttons.
  2. Borrow different eyes. DevTools → Rendering panel → Emulate vision deficiencies. Try blurred vision against the gray text, then protanopia against the stock dots. Which color is in stock now?
  3. Ask for calm. Rendering panel → Emulate prefers-reduced-motion: reduce. The broken badge keeps pulsing at you; the fixed one goes still.
  4. Grow older. Browser settings → set default font size to Very Large. The fixed store scales; the broken store's px text ignores you. On a phone, try to pinch zoom the broken store.
  5. Listen. Turn on VoiceOver (Cmd+F5), Narrator (Win+Ctrl+Enter), or NVDA. Pull up the headings list on each store. One has an outline; one is an undifferentiated slab. Find the nav on the broken store. (You won't — it's aria-hidden.)
  6. Then audit. Run Lighthouse or axe on both. Note what the scanner caught — and that automated tools find well under half of real accessibility failures. The broken store's invisible-to-tools sins are numbered in its source; diff them against the fixes.

The lesson is the same choice as ever: semantic HTML plugs your page into machinery the platform already built — screen readers, keyboards, user preferences, future devices. Div soup unplugs it, one convenience at a time.

Next rung

The page can be perceived and operated. Can it be read? Continue to Internationalization: the web speaks every language — then on to Usability.