WCAG 2.3.3: Animation from Interactions
The user scrolls; the page answers with parallax layers, zooming heroes, and elements swooping in from the sides. For someone with a vestibular disorder, that answer can mean minutes — or hours — of dizziness and nausea. Motion animation triggered by interaction must be disableable, unless the animation is essential. In practice, one CSS media query — prefers-reduced-motion — carries most of the load.
The success criterion, in full
Motion animation triggered by interaction can be disabled, unless the animation is essential to the functionality or the information being conveyed.
Two defined terms do the work. Motion animation: adding steps between conditions to create the illusion of movement or smooth transition — movement, not color changes, blurs, or opacity fades. Essential: if removed, the information or functionality would fundamentally change. Decoration is never essential.
Who this helps
The vestibular system in the inner ear tells the brain how the body is moving. When the eyes report large-scale motion that the inner ear does not feel — exactly what parallax and scroll-linked effects produce — the mismatch can cause real, physical illness:
People with vestibular disorders
Vestibular migraine, Ménière's disease, labyrinthitis, post-concussion syndrome. Symptoms include vertigo, nausea, headaches, and disorientation that can last hours after exposure.
People with migraine disorders
Moving backgrounds and animated transitions are documented migraine triggers for many people, independent of any vestibular diagnosis.
Some autistic users and people with ADHD
Ambient and reactive motion can be overwhelming or make it impossible to focus on the actual content.
Anyone prone to motion sickness
The same mechanism as car sickness — visual motion without physical motion — operating in reverse.
These users typically enable “Reduce motion” in their OS settings once — and then depend on every site to honor it. The criterion turns that dependency into a requirement.
What the criterion covers — and what it doesn’t
In scope: interaction-triggered motion
- Parallax scrolling — layers moving at different speeds as the user scrolls.
- Scroll-triggered reveals: elements sliding, zooming, or rotating into view.
- Scroll-linked effects: heroes that scale, pin, or morph with scroll position.
- Hover- and click-triggered movement: magnetic buttons, springy cards, shake effects.
- Animated page transitions that fly or slide content when a link is activated.
Out of scope (for this criterion)
- Color changes, opacity fades, and blurs — explicitly not motion animation.
- Autoplaying motion (carousels, background video) — that is 2.2.2 Pause, Stop, Hide territory.
- Flashing — covered by 2.3.1 and 2.3.2.
- The scrolling itself: content moving because the user scrolls is the interaction, not an added animation.
- Essential animation, where motion is the information — rare, and never mere decoration.
“Can be disabled” does not require removing your animations for everyone. It requires a working off-switch: honoring the OS-level reduce-motion signal, offering a site toggle, or both. Users who enjoy motion keep it; users it harms escape it.
prefers-reduced-motion in practice
CSS: neutralize motion, keep meaning
Prefer replacing movement with an instant or fading equivalent rather than deleting feedback entirely. A robust site-wide baseline plus targeted overrides:
/* Motion is the default experience… */
.card { transition: transform 300ms ease; }
.card:hover { transform: translateY(-8px); }
.hero__bg { animation: drift 30s linear infinite alternate; }
/* …but it can be disabled. */
@media (prefers-reduced-motion: reduce) {
.card { transition: none; }
.card:hover { transform: none; box-shadow: 0 0 0 2px currentColor; }
.hero__bg { animation: none; }
/* Blunt but effective site-wide guard */
*, *::before, *::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
scroll-behavior: auto !important;
}
}JavaScript: gate animation libraries and scroll effects
JS-driven parallax, GSAP/ScrollTrigger scenes, and smooth-scroll libraries bypass CSS — gate them explicitly and react to live changes:
const motionQuery = window.matchMedia("(prefers-reduced-motion: reduce)");
function setupEffects() {
if (motionQuery.matches) {
// Reduced: static layout, content fully present, no scroll-linking
document.documentElement.classList.add("reduced-motion");
parallax?.destroy();
return;
}
parallax = new ParallaxController("[data-parallax]");
initScrollReveals(); // ensure reveals default to visible without JS motion
}
setupEffects();
// Users can flip the OS setting mid-session — respond without a reload
motionQuery.addEventListener("change", setupEffects);A site-level toggle for users who don’t know the OS setting
<button type="button" id="motion-toggle" aria-pressed="false">
Reduce motion
</button>
<script>
const saved = localStorage.getItem("reduceMotion") === "true";
applyMotionPreference(saved);
motionToggle.addEventListener("click", () => {
const next = motionToggle.getAttribute("aria-pressed") !== "true";
motionToggle.setAttribute("aria-pressed", String(next));
localStorage.setItem("reduceMotion", String(next));
applyMotionPreference(next);
});
function applyMotionPreference(reduce) {
document.documentElement.classList.toggle("reduced-motion", reduce);
}
</script>
<style>
/* Same rules fire for the OS signal and the site toggle */
.reduced-motion .hero__bg { animation: none; }
</style>Pass and fail examples
✓ Passes 2.3.3
- A marketing site with rich parallax that collapses to a static layout when prefers-reduced-motion is set.
- Scroll reveals that become simple opacity fades (not movement) under reduce-motion.
- An app with an in-product “reduce motion” setting that persists and covers all transitions.
- A physics-teaching demo whose motion is the lesson — plausibly essential — offered alongside a step-frame mode anyway.
✗ Fails 2.3.3
- A portfolio with heavy scroll-jacking and parallax that ignores prefers-reduced-motion entirely.
- Reveal-on-scroll cards that still slide 100px into place with the OS setting on.
- “Smooth scroll” libraries that keep animating anchor jumps under reduce-motion.
- A reduce-motion implementation that hides the animated content instead of showing it at rest — content must remain available.
Common failures
- Not querying prefers-reduced-motion at all — still the default state of most parallax and scroll-animation implementations.
- Covering CSS animations but not JS-driven ones: GSAP timelines, ScrollTrigger scenes, Lottie files, and smooth-scroll libraries keep moving.
- Reveal-on-scroll elements that stay invisible under reduce-motion because the 'reveal' animation never runs — always default content to visible.
- Only reducing durations ('faster is fine, right?') — a 100ms parallax lurch is still motion; replace movement with fades or nothing.
- Ignoring live preference changes, so users must reload after flipping the OS switch mid-session.
- Claiming brand delight as 'essential' — essential means the information or functionality would fundamentally change, not the vibe.
- A site toggle that exists but is buried, unlabeled, or forgets its state on the next page load.
How to test for 2.3.3
- 1
Catalog interaction-triggered motion
Scroll every key page slowly, hover interactive elements, trigger transitions. Note each place where content moves because of your action: parallax, reveals, scroll-linked scaling, springy hovers, animated route changes.
- 2
Enable reduce-motion at the OS level
macOS: System Settings → Accessibility → Display → Reduce motion. Windows: Settings → Accessibility → Visual effects → Animation effects off. Or emulate prefers-reduced-motion in Chrome DevTools Rendering panel.
- 3
Repeat the walkthrough
Every cataloged motion should now be gone or replaced with a non-motion equivalent (instant change or fade). Anything still sliding, zooming, or drifting is a failure — check JS-driven effects especially.
- 4
Verify content survives the reduction
Confirm nothing is missing: scroll-revealed sections must be visible, functionality reachable, and layout intact. Disabling animation must never disable content.
- 5
Test the live change and any site toggle
Flip the OS setting while the page is open — well-built pages respond without reload. If a site-level toggle exists, confirm it covers the same effects and persists across pages and visits.
Automated tools can detect whether a stylesheet mentions prefers-reduced-motion, but only a manual walkthrough proves the motion actually stops. Fold this into the full WCAG 2.2 checklist.
Frequently asked questions
What does WCAG 2.3.3 Animation from Interactions require?
It requires that motion animation triggered by interaction can be disabled, unless the animation is essential to the functionality or the information being conveyed. 'Triggered by interaction' means the motion happens because the user did something — scrolled, clicked, hovered, dragged — where the user's action did not inherently require that motion. Parallax scrolling is the canonical example: the user asked to scroll; the layered drifting of background images is an added effect that must be disableable.
What is 'motion animation', exactly?
The WCAG definition is the addition of steps between conditions to create the illusion of movement, or to create a sense of smooth transition — think elements sliding, zooming, drifting, or the viewport gliding. Changes of color, blurring, and opacity fades are explicitly not motion animation, so a simple crossfade is fine even with reduce-motion on. The harm model is vestibular: it is movement across the visual field, especially large or parallax movement, that triggers dizziness and nausea.
Is honoring prefers-reduced-motion enough to conform?
Yes — respecting the operating system's reduce-motion setting via the prefers-reduced-motion media query is the primary documented technique (C39). Every major OS exposes the setting and every modern browser reports it. A site-level motion toggle is a valuable addition (it helps users who don't know about the OS setting), but the media query is the baseline: if your interaction-triggered motion ignores prefers-reduced-motion, users have no reliable way to disable it.
When is animation 'essential' and therefore exempt?
Essential means removing the animation would fundamentally change the information or functionality — not merely make it less delightful. Examples that plausibly qualify: the motion of pieces in an animation-based game, a physics simulation being taught, or a page-position indicator whose movement is the information. Examples that do not qualify: parallax backgrounds, scroll-triggered reveals, magnetic hover effects, springy page transitions, and zooming hero images. If the same information can be shown at rest, the animation is decoration and must be disableable.
How does 2.3.3 differ from 2.2.2 Pause, Stop, Hide and 2.3.1/2.3.2?
2.2.2 (A) covers content that moves by itself — carousels, tickers, autoplaying video — and requires pause/stop/hide controls. 2.3.1 (A) and 2.3.2 (AAA) cover flashing, which is a seizure risk. 2.3.3 (AAA) fills the remaining gap: motion that happens in response to the user's own interaction. A parallax page never 'auto-plays' (so 2.2.2 does not catch it) and never flashes (so 2.3.x flashing rules do not catch it), yet it is one of the most common triggers of vestibular symptoms — that is precisely why 2.3.3 was added in WCAG 2.1.
Who is affected by interaction-triggered motion?
People with vestibular (inner-ear) disorders — including vestibular migraine, Ménière's disease, and post-concussion syndrome — for whom moving visual fields can cause dizziness, nausea, headaches, and disorientation severe enough to require lying down. An estimated large share of adults experience vestibular dysfunction at some point. Motion sensitivity also affects people with migraine disorders and some autistic users. Unlike a seizure trigger, the reaction can build over seconds, but it can end computer use for hours.
Related Success Criteria
Content does not contain anything that flashes more than three times per second.
Web pages do not contain anything that flashes more than three times per second.
All functionality is available from a keyboard interface.
Focus can be moved away from any component using standard keyboard methods.
All functionality is available from a keyboard interface without exception.