Motion, zoom and targets

Respect a setting somebody has already made, and survive a screen that is not yours.

14of 16
≈ 12Min read
5Parts

Motion can make people ill

Parallax, large sliding panels, zooming transitions and autoplaying video cause nausea, dizziness and migraine for people with vestibular disorders — a group about as large as the one that uses a screen reader. The operating system has a switch for it, and the browser tells you.

the query, and the sensible default
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

A blanket rule like that is a good safety net. A considered version is better: keep a small fade (opacity is not motion), and remove the movement — translation, scale, parallax, spin.

And it is not only CSS

Autoplaying anything longer than five seconds needs a way to pause it — that is a WCAG criterion of its own, and it applies to carousels, tickers and background video.

JavaScript animation has to ask too
const still = matchMedia("(prefers-reduced-motion: reduce)").matches;

element.animate(frames, { duration: still ? 0 : 400 });
window.scrollTo({ top: 0, behavior: still ? "auto" : "smooth" });

// and a video that plays by itself
if (!still) video.play();

Zoom, and the meta tag that breaks it

Blocking zoom is a failure on its own, and it is the single most common accessibility bug on mobile sites. People zoom because they cannot read it otherwise.

Beyond that: the page must work at 200% zoom, and reflow into a 320 CSS pixel column without horizontal scrolling. That is what somebody at 400% on a laptop is actually looking at — a phone-width viewport, on a desktop layout.

never do this
<meta name="viewport" content="width=device-width, user-scalable=no, maximum-scale=1">

<!-- the one to ship -->
<meta name="viewport" content="width=device-width, initial-scale=1">
Test it in thirty seconds

Set the browser to 400% zoom on a page you built. Anything that needs sideways scrolling, any text that is cut off, any control that has moved off-screen is a bug. It is the fastest accessibility check there is.

Text that can be resized

Font sizes in rem scale with the user's browser setting; sizes in px do not. A layout with fixed heights and overflow: hidden clips text the moment somebody raises their default size — which a surprising number of people have done and never mention.

Let containers grow. min-height instead of height, and no white-space: nowrap on anything that could be a sentence.

Targets you can hit

WCAG 2.2 asks for 24 by 24 CSS pixels minimum, with exceptions for inline links in text. The platform guidelines are more generous — 44×44 on iOS, 48×48 on Android — and those are the numbers to design to. Padding counts; the icon does not have to be that big.

Spacing matters as much as size: two 24px buttons touching each other are harder to hit than two 24px buttons with 8px between them, and the criterion measures the space around the target too.

Practice