Animation, Motion Sensitivity, and Web Accessibility
Animation and motion are powerful design tools. They guide attention, communicate state changes, and create a sense of polish. But for millions of people, motion on screen is not just distracting — it is physically harmful. Vestibular disorders, epilepsy, migraines, and other conditions can make animated interfaces nauseating, disorienting, or dangerous. Building accessible motion means understanding who is affected, what the relevant WCAG criteria require, and how to implement motion as an enhancement that users can control.
Why Motion Accessibility Matters
The web has become increasingly animated. Parallax scrolling, page transitions, loading spinners, background videos, hover effects, scroll-triggered animations — modern websites are rarely still. This creates real problems for several groups of people:
- Vestibular disorders affect the inner ear and brain's ability to process spatial orientation and movement. When the screen moves but the body does not, people with vestibular conditions experience vertigo, dizziness, nausea, and disorientation. This is not mild discomfort — it can be debilitating and persist for hours after exposure.
- Photosensitive epilepsy means that flashing or flickering content can trigger seizures. This is a medical emergency, not an inconvenience. The threshold is well-defined: content that flashes more than three times per second can provoke seizures in susceptible individuals.
- Cognitive load and attention disorders — for people with ADHD, autism, or cognitive disabilities, constant motion competes for attention and makes it difficult or impossible to focus on content. Animation that a neurotypical user barely notices can be overwhelming for someone whose brain processes all visual input at equal priority.
- Migraines — motion, particularly smooth or oscillating animation, can trigger migraines in susceptible individuals. Once triggered, a migraine can last hours or days.
- Autism spectrum conditions — sensory sensitivity is common, and animated interfaces can cause sensory overload, anxiety, and avoidance of the content entirely.
The scale of this problem is significant. Vestibular disorders alone affect roughly 35% of adults over age 40 to some degree. When you include migraines (affecting approximately 12% of the population), epilepsy (1%), ADHD (5-7% of children, 2-5% of adults), and autism spectrum conditions (1-2%), the number of users who benefit from motion control is substantial.
Who Is Affected
People with vestibular disorders — conditions like benign paroxysmal positional vertigo (BPPV), Ménière's disease, vestibular neuritis, and labyrinthitis affect the balance system. Scrolljacking, parallax effects, and large-scale motion can trigger vertigo episodes. Some users cannot use a website at all if it has aggressive scroll-based animation.
People with epilepsy — photosensitive epilepsy is the most direct risk. Rapidly flashing content, high-contrast strobing, and certain patterns (particularly red-saturated flashing) can cause seizures. The 1997 Pokémon incident, where a cartoon episode caused seizures in nearly 700 Japanese children, remains the most well-known example.
People with ADHD — attention regulation is the core challenge. Animated banners, auto-playing videos, and looping animations constantly pull focus away from the task the user is trying to complete. This is not a preference — it is a neurological barrier to using the interface.
People with migraines — visual triggers vary by individual but commonly include rapid movement, flashing, high contrast patterns, and certain color combinations. A website that triggers a migraine has effectively prevented access for the rest of the day.
People with autism spectrum conditions — hypersensitivity to visual stimuli is common. Unexpected motion, complex animation sequences, and constantly moving elements create sensory overload that can lead to anxiety, inability to process content, and in some cases meltdowns.
People with traumatic brain injuries — concussions and other brain injuries frequently result in motion sensitivity that can persist for months or years. Screen-based motion exacerbates symptoms including headache, dizziness, and difficulty concentrating.
WCAG Criteria for Motion
WCAG addresses motion through several specific success criteria. Understanding each one is essential for compliance and for protecting users from harm.
2.2.2 Pause, Stop, Hide (Level A) — this criterion requires that any content which moves, blinks, or scrolls automatically, and which starts automatically and lasts more than five seconds, must have a mechanism for the user to pause, stop, or hide it. This applies to carousels, auto-advancing slideshows, animated banners, auto-playing video, news tickers, and any decorative animation that runs continuously. The key word is "automatically" — if the user explicitly starts the animation (by clicking a play button, for example), this criterion does not apply to the initial activation, but the user must still be able to stop it.
2.3.1 Three Flashes or Below Threshold (Level A) — content must not flash more than three times in any one-second period, unless the flash is below the general flash and red flash thresholds. This is a hard limit with no exceptions. The thresholds are precisely defined: a general flash is a pair of opposing changes in relative luminance of 10% or more of the maximum relative luminance where the darker image has a relative luminance below 0.80; a red flash is a pair of opposing transitions involving a saturated red. If your content flashes, you must either keep it below three flashes per second or demonstrate that the flash area and intensity fall below the defined thresholds.
2.3.2 Three Flashes (Level AAA) — this is the stricter version. Content must not flash more than three times in any one-second period, full stop. No threshold exceptions. If you are targeting AAA compliance, no flashing at all above three times per second is permitted regardless of intensity or area.
2.3.3 Animation from Interactions (Level AAA, introduced in WCAG 2.1) — motion animation triggered by user interaction can be disabled, unless the animation is essential to the functionality or the information being conveyed. This criterion directly addresses the situation where scrolling, clicking, or hovering triggers animations that cause vestibular distress. The user must have a way to turn off non-essential motion. This is where the prefers-reduced-motion media query becomes particularly important.
The prefers-reduced-motion Media Query
Modern operating systems allow users to indicate that they prefer reduced motion. On macOS, this is System Settings → Accessibility → Display → Reduce motion. On iOS, Settings → Accessibility → Motion → Reduce Motion. On Windows, Settings → Ease of Access → Display → Show animations. On Android, Settings → Accessibility → Remove animations. The prefers-reduced-motion CSS media query lets websites detect this preference and respond accordingly.
The media query has two values: reduce (the user has indicated they prefer less motion) and no-preference (the user has not expressed a preference or the system does not support the setting).
CSS Implementation
The most straightforward approach is to define your animations normally, then disable or reduce them when the user prefers reduced motion:
/* Normal animation */
.fade-in {
animation: fadeIn 0.3s ease-out;
}
@keyframes fadeIn {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
}
/* Reduced motion: keep the fade, remove the movement */
@media (prefers-reduced-motion: reduce) {
.fade-in {
animation: fadeInSimple 0.1s ease-out;
}
@keyframes fadeInSimple {
from { opacity: 0; }
to { opacity: 1; }
}
}
A more comprehensive approach is to use a global rule that disables all transitions and animations when reduced motion is preferred:
@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;
}
}
This blanket rule is effective as a baseline, but be aware that it removes all animation, including subtle fades and opacity changes that are generally safe. A more nuanced approach selectively reduces only the motion that causes problems:
@media (prefers-reduced-motion: reduce) {
/* Remove parallax */
.parallax-section {
background-attachment: scroll;
transform: none;
}
/* Disable scroll-triggered animations */
.animate-on-scroll {
opacity: 1;
transform: none;
}
/* Stop continuous animations */
.rotating-element,
.bouncing-element,
.pulsing-element {
animation: none;
}
/* Keep fades but make them instant */
.fade-transition {
transition: opacity 0.1s ease;
}
/* Disable smooth scrolling */
html {
scroll-behavior: auto;
}
}
JavaScript Detection
For animations controlled by JavaScript, you can detect the motion preference using the matchMedia API:
const prefersReducedMotion = window.matchMedia(
'(prefers-reduced-motion: reduce)'
);
if (prefersReducedMotion.matches) {
// Use simplified or no animation
element.style.opacity = '1';
} else {
// Use full animation
animateElement(element);
}
// Listen for changes (user toggles setting while page is open)
prefersReducedMotion.addEventListener('change', (event) => {
if (event.matches) {
stopAllAnimations();
} else {
restoreAnimations();
}
});
For animation libraries like GSAP or Framer Motion, check the preference before initializing animations and provide reduced alternatives:
const reducedMotion = window.matchMedia(
'(prefers-reduced-motion: reduce)'
).matches;
const duration = reducedMotion ? 0 : 0.6;
const distance = reducedMotion ? 0 : 50;
gsap.from('.hero-title', {
opacity: 0,
y: distance,
duration: duration
});
Safe Animation Patterns
Not all animation is problematic. Certain types of motion are generally well-tolerated even by people with motion sensitivity:
- Opacity changes (fades) — fading elements in and out does not involve spatial movement and is rarely a vestibular trigger. Keep fade durations short (under 300ms).
- Color transitions — smoothly changing color (for example, a button changing background color on hover) involves no motion and is safe.
- Small-scale transforms — very subtle movements of a few pixels, such as a slight lift on hover, are generally tolerable. The key is "small" — a 2-pixel shift is different from a 200-pixel slide.
- Scale changes under 10% — a button that scales from 1.0 to 1.05 on hover is minimal enough to be safe for most users.
- Underline animations on links — expanding or sliding underlines on text links involve tiny amounts of motion and are safe.
The guiding principle is that animation which does not create a sense of spatial movement — where things are not flying across the screen, sliding in from off-screen, or creating the illusion of depth and perspective — is generally safe.
Dangerous Animation Patterns
Certain animation patterns are particularly problematic and should always be controlled by the reduced motion preference:
- Parallax scrolling — background and foreground elements moving at different speeds creates a depth illusion that is a major vestibular trigger. This is one of the most commonly reported causes of motion sickness on the web.
- Full-screen transitions — page transitions where the entire viewport slides, fades through black, or morphs are disorienting. The entire visual field changing at once is a strong vestibular trigger.
- Zoom and scale effects — elements that grow from small to full size, or that zoom in on scroll, create a looming effect that triggers vestibular responses.
- Spinning and rotation — rotating elements, loading spinners, and carousel transitions that rotate around an axis are problematic. Consider replacing spinning loaders with pulsing dots or progress bars.
- Scroll hijacking (scrolljacking) — overriding native scroll behavior to create custom scroll speeds, snap points, or scroll-triggered animations removes user control and is a major accessibility barrier.
- Bouncing and elastic effects — elements that overshoot their target and bounce back, or elastic scrolling effects, involve oscillation that is particularly problematic for vestibular conditions.
- Continuous background animation — animated gradients, floating particles, or moving background patterns that never stop create persistent visual noise.
- Large-distance sliding — elements that slide in from off-screen or travel across a significant portion of the viewport are more problematic than elements that appear with a short fade.
Autoplay Video and Animated Backgrounds
Auto-playing video backgrounds have become common in hero sections, and they present several accessibility challenges simultaneously. They create constant motion, may contain flashing content, consume bandwidth, and distract from primary content.
If you use background video, you must provide a way to pause it (WCAG 2.2.2). Best practice is to respect prefers-reduced-motion by not auto-playing the video at all for users who prefer reduced motion — show the first frame as a static image instead:
<video
class="hero-video"
autoplay
muted
loop
playsinline
poster="hero-still.jpg"
>
<source src="hero.mp4" type="video/mp4">
</video>
<button class="video-toggle" aria-label="Pause background video">
Pause
</button>
@media (prefers-reduced-motion: reduce) {
.hero-video {
display: none;
}
.hero-section {
background-image: url('hero-still.jpg');
background-size: cover;
}
}
const video = document.querySelector('.hero-video');
const toggle = document.querySelector('.video-toggle');
// Respect system preference
if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) {
video.pause();
video.removeAttribute('autoplay');
}
// Provide manual control
toggle.addEventListener('click', () => {
if (video.paused) {
video.play();
toggle.textContent = 'Pause';
toggle.setAttribute('aria-label', 'Pause background video');
} else {
video.pause();
toggle.textContent = 'Play';
toggle.setAttribute('aria-label', 'Play background video');
}
});
Animated GIFs present a particular challenge because they cannot be paused natively. If you use animated GIFs, provide a static alternative or use the <picture> element with a media query, or replace GIFs with <video> elements that can be controlled.
Flashing Content and Photosensitive Epilepsy
Flashing content is the most dangerous motion accessibility issue because the consequences are immediate and severe. A seizure triggered by flashing content is a medical emergency.
The Harding test (also called the Harding Flash and Pattern Analyzer) is an industry-standard tool used by broadcasters to analyze video content for seizure risk. It evaluates luminance changes, red flash intensity, and spatial patterns frame by frame. While the full Harding analysis tool is proprietary and used primarily in broadcast, the principles it checks against are the same ones encoded in WCAG 2.3.1.
Specific risk factors for triggering photosensitive seizures include:
- Flashing faster than three times per second
- High contrast between flash states (particularly transitioning between very dark and very bright)
- Large flash area — the risk increases as the flashing area covers more of the visual field. WCAG defines the threshold as any set of pixels covering more than 25% of a 10-degree visual field (roughly 341 by 256 pixels at typical viewing distance)
- Saturated red — red flashes are particularly dangerous and have a lower threshold
- Geometric patterns — high-contrast stripes, grids, and concentric patterns can trigger seizures even without temporal flashing, through a mechanism called pattern-sensitive epilepsy
If your content includes any form of flashing, strobing, or rapid luminance change, it must be tested. The free Photosensitive Epilepsy Analysis Tool (PEAT) from the Trace Center can analyze video content for seizure risk. For web animations, manually verify that no element flashes more than three times per second. When in doubt, do not flash.
Infinite Scrolling and Motion
Infinite scroll — where new content loads continuously as the user scrolls — creates motion issues beyond the obvious. As content loads and the page extends, layout shifts push existing content to new positions. This creates unexpected movement that the user did not initiate and cannot predict. For users with vestibular conditions, the combination of scrolling, loading, and shifting is a compound trigger.
Accessible alternatives to infinite scroll include:
- Traditional pagination with clear page numbers
- A "Load more" button that the user explicitly activates
- A defined content area that scrolls internally while the page frame remains fixed
If you must use infinite scroll, minimize layout shift by reserving space for incoming content (using placeholder containers with defined heights), and ensure that loading new content does not cause existing content to jump.
Loading Animations and Skeleton Screens
Loading indicators are functional — they communicate that something is happening. But a spinning wheel or pulsing dots are still animation, and for users who need reduced motion, they should be simplified.
Skeleton screens (gray placeholder shapes that indicate where content will appear) are generally better than spinners because they involve no motion by default. If you add a shimmer effect to skeleton screens — the common pattern of a light gradient sweeping across the placeholder — that shimmer should be disabled for users who prefer reduced motion:
.skeleton {
background: #e5e7eb;
border-radius: 4px;
}
.skeleton-shimmer {
background: linear-gradient(
90deg,
#e5e7eb 25%,
#f3f4f6 50%,
#e5e7eb 75%
);
background-size: 200% 100%;
animation: shimmer 1.5s infinite;
}
@keyframes shimmer {
0% { background-position: 200% 0; }
100% { background-position: -200% 0; }
}
@media (prefers-reduced-motion: reduce) {
.skeleton-shimmer {
animation: none;
background: #e5e7eb;
}
}
For loading spinners, consider replacing the rotation with a simple opacity pulse or a static "Loading..." text label when reduced motion is preferred.
Motion as Enhancement, Not Requirement
The core principle of accessible animation is that motion should be an enhancement layer, never a requirement. Every interaction and piece of content must be fully functional and comprehensible without any animation. This means:
- Content must be visible without animation. If an element is hidden (opacity: 0) until an animation triggers, ensure that the element is immediately visible when animation is disabled. Users with reduced motion should not see empty spaces where content was supposed to animate in.
- State changes must be communicated without motion. If a button press triggers a slide-out panel, the panel should still appear when motion is reduced — just without the sliding. An instant state change (display: none to display: block) is perfectly acceptable.
- Navigation must work without transitions. If page navigation involves a transition animation, the destination page must load immediately when animation is disabled.
- Meaning must not depend on animation. If an animation communicates something (a success checkmark drawing itself, a progress indicator filling up), the same information must be available statically — a completed checkmark icon, a filled progress bar.
A useful mental model: design and build the interface first with zero animation. Make sure everything works, is usable, and communicates clearly. Then add animation as a progressive enhancement for users who can benefit from it.
Testing for Motion Sensitivity
Testing motion accessibility requires both automated and manual approaches:
- Enable reduced motion on your operating system and browse your site. Every animation should either stop, simplify, or be replaced with a non-motion alternative. Nothing should break.
- Check for auto-playing content. Load every page and note anything that moves without user interaction. Each moving element must have a pause/stop control or be disabled by reduced motion preference.
- Check for flashing. Record suspect content and use PEAT or manual frame-by-frame analysis. Check animated GIFs, video content, and CSS animations that involve rapid color or opacity changes.
- Test with screen readers. Animations should not interfere with screen reader navigation. Ensure that dynamically loaded content (from scroll-triggered animations) is accessible to screen readers regardless of animation state.
- Test keyboard navigation. Focus indicators should remain visible and functional even during animations. An element that is mid-animation should still receive and display focus correctly.
- Check that all content is reachable. If animation is disabled and content was set to appear via animation, verify that all content is visible and no sections are hidden.
- Test the pause/stop controls. For any auto-playing content, verify that pause and stop controls are keyboard-accessible, properly labeled, and functional.
Browser DevTools can help: Chrome's Rendering panel has an "Emulate CSS media feature prefers-reduced-motion" option. Firefox offers a similar toggle in its accessibility inspector.
Real-World Examples of Good Motion Accessibility
Apple — Apple's website makes extensive use of scroll-triggered animation, parallax, and video. However, when "Reduce Motion" is enabled on macOS or iOS, the site respects this preference comprehensively. Scroll-triggered animations resolve instantly to their final state, parallax effects are disabled, and auto-playing videos are replaced with static images. Apple's approach demonstrates that a site can be visually rich for users who want that experience while remaining fully accessible for those who do not.
Google Material Design — Google's Material Design system includes explicit guidance for reduced motion. Their component library provides reduced-motion variants that replace sliding and scaling transitions with simple fades or instant state changes. Durations are shortened, distances are reduced, and non-essential animation is removed entirely. The underlying functionality remains identical.
Stripe — Stripe's marketing pages feature smooth animations and gradient effects, but the site detects the reduced motion preference and simplifies its animations accordingly. Interactive elements remain functional, and content that would normally animate into view is displayed immediately.
These examples share a common approach: they build the full experience with animation, but every animated element has a defined reduced-motion fallback. No content is lost, no functionality is removed — only the motion layer changes.
Motion Accessibility Checklist
Use this checklist to verify that your site handles motion accessibly:
- All auto-playing animations, videos, and carousels have visible pause/stop controls
- Auto-playing content stops or does not start when
prefers-reduced-motion: reduceis active - No content flashes more than three times per second
- Parallax effects are disabled when reduced motion is preferred
- Scroll-hijacking and custom scroll behaviors are disabled when reduced motion is preferred
- Page transitions are instant (no slide, zoom, or morph) when reduced motion is preferred
- All content is visible and reachable without any animation running
- Loading indicators have reduced-motion alternatives (static text or non-animated placeholders)
- Animated GIFs have static alternatives or can be paused
- CSS
scroll-behavior: smoothis overridden toautowhen reduced motion is preferred - JavaScript animations check
matchMedia('(prefers-reduced-motion: reduce)')before running - Animation libraries (GSAP, Framer Motion, Lottie) are configured to respect the reduced motion preference
- Background videos show a static poster image when reduced motion is preferred
- No meaning or content is lost when all animation is disabled
- Skeleton screen shimmer effects are disabled when reduced motion is preferred
- Focus indicators remain visible and functional during and after animations
- WCAG 2.2.2 (Pause, Stop, Hide) is met for all auto-playing content
- WCAG 2.3.1 (Three Flashes) is met for all content
- The site has been tested with the operating system's reduced motion setting enabled
Достъпен ли е вашият уебсайт?
Сканирайте уебсайта си безплатно и получете вашия WCAG резултат за минути.
Сканирайте сайта си безплатно