How Do You Meet WCAG 2.3.3 Animation from Interactions?
TABLE OF CONTENTS
- Key Takeaways
- Understanding WCAG 2.3.3 Requirements
- Why Animation Accessibility Matters
- The Essential Animation Exception
- Implementing prefers-reduced-motion
- Animation Patterns and Solutions
- Providing User Controls
- Testing for Compliance
- Common Implementation Mistakes
- Framework-Specific Implementation
- Frequently Asked Questions
- Related Resources
WCAG 2.3.3 Animation from Interactions requires that motion animation triggered by user interaction can be disabled unless the animation is essential to functionality. This Level AAA criterion protects approximately 35% of adults over 40 who experience vestibular disorders, for whom unexpected motion can cause nausea, dizziness, and disorientation. With motion-heavy designs becoming increasingly common, understanding how to implement accessible animations is critical for inclusive user experiences.
Key Takeaways
This guide covers everything you need to implement WCAG 2.3.3 compliant animations.
- WCAG 2.3.3 is a Level AAA criterion requiring user control over non-essential motion animations
- Vestibular disorders affect 35% of adults over 40, making motion sensitivity a significant accessibility concern
- The CSS `prefers-reduced-motion` media query provides the primary implementation method
- Essential animations (those required for functionality) are exempt from this requirement
- Parallax scrolling, zoom animations, and spinning elements are the most common violations
Understanding WCAG 2.3.3 Requirements
Success Criterion 2.3.3 Animation from Interactions states:
> "Motion animation triggered by interaction can be disabled, unless the animation is essential to the functionality or the information being conveyed."
This criterion specifically addresses animations that occur in response to user actions—not continuous background animations (covered by 2.2.2 Pause, Stop, Hide) or flashing content (covered by 2.3.1 Three Flashes).
What Triggers This Criterion
The criterion applies to motion that is:
- Initiated by user interaction (clicking, scrolling, hovering)
- Non-essential to the core functionality
- Capable of causing vestibular discomfort
Common Triggering Animations
+-------------------------+------------------+-----------------------------+
| Animation Type | User Trigger | Common Issues |
+-------------------------+------------------+-----------------------------+
| Parallax scrolling | Scroll | Large-scale motion |
+-------------------------+------------------+-----------------------------+
| Page transitions | Navigation | Full-screen movement |
+-------------------------+------------------+-----------------------------+
| Hover zoom effects | Mouse hover | Sudden size changes |
+-------------------------+------------------+-----------------------------+
| Carousel slides | Click/swipe | Sliding motion |
+-------------------------+------------------+-----------------------------+
| Accordion expansion | Click | Content shifting |
+-------------------------+------------------+-----------------------------+
| Modal appearances | Click | Zoom or slide entrances |
+-------------------------+------------------+-----------------------------+Why Animation Accessibility Matters
Vestibular disorders affect the inner ear and brain's ability to process motion. When users with these conditions encounter unexpected animations, they can experience:
Physical Symptoms
- Vertigo and dizziness
- Nausea and motion sickness
- Headaches and migraines
- Disorientation and confusion
- Difficulty focusing
Affected Populations
Understanding who benefits from motion control helps prioritize implementation:
- Vestibular disorder patients: 35% of adults over 40 experience vestibular dysfunction
- Migraine sufferers: Motion sensitivity affects 85% of migraine patients
- Post-concussion individuals: Motion intolerance is common after traumatic brain injury
- Autistic individuals: Many experience sensory sensitivities including motion
- Users with cognitive disabilities: Unexpected motion can disrupt focus and comprehension
The Essential Animation Exception
WCAG 2.3.3 exempts animations that are "essential to the functionality or the information being conveyed." Understanding this exception prevents over-application of motion restrictions.
Examples of Essential Animation
Loading indicators: A spinning loader communicates that content is being retrieved. Without it, users might think the interface is frozen.
Progress indicators: Animated progress bars show ongoing processes. Static alternatives (percentage text) can supplement but not fully replace the motion feedback.
Data visualization: Animated transitions in charts help users understand data relationships. A bar growing from zero to its value shows the comparison more effectively than static display.
Interactive feedback: Button press animations confirm user actions. A brief scale or color transition provides essential feedback.
Non-Essential Animation Examples
Parallax scrolling: Background images moving at different speeds than foreground content is purely decorative.
Bouncing elements: "Attention-grabbing" bounce animations on buttons or icons serve no functional purpose.
Decorative transitions: Elaborate page transitions between navigation may look impressive but aren't essential to the navigation function.
Auto-playing carousels: Sliding content that moves without user initiation is never essential (users can manually navigate).
Implementing prefers-reduced-motion
The CSS `prefers-reduced-motion` media query is the primary tool for WCAG 2.3.3 compliance. It detects when users have enabled reduced motion settings in their operating system.
Basic CSS Implementation
/* Default: Full animation */
.animated-element {
transition: transform 0.3s ease-in-out;
}
.animated-element:hover {
transform: scale(1.1);
}
/* Reduced motion: Remove or minimize animation */
@media (prefers-reduced-motion: reduce) {
.animated-element {
transition: none;
}
.animated-element:hover {
transform: none;
}
}Progressive Enhancement Approach
Some developers prefer a "motion-safe" approach where animations are opt-in rather than opt-out:
/* Default: No animation */
.animated-element {
/* Static styling */
}
/* Only animate if user hasn't requested reduced motion */
@media (prefers-reduced-motion: no-preference) {
.animated-element {
transition: transform 0.3s ease-in-out;
}
.animated-element:hover {
transform: scale(1.1);
}
}This approach is considered more accessible because it defaults to the safer option.
JavaScript Detection
For animations controlled via JavaScript, detect the preference programmatically:
// Check if user prefers reduced motion
const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)');
function handleAnimation() {
if (prefersReducedMotion.matches) {
// Use instant transitions or skip animation
element.style.opacity = '1';
} else {
// Use full animation
element.animate([
{ opacity: 0, transform: 'translateY(20px)' },
{ opacity: 1, transform: 'translateY(0)' }
], { duration: 300, easing: 'ease-out' });
}
}
// Listen for changes (user might toggle setting)
prefersReducedMotion.addEventListener('change', handleAnimation);Animation Patterns and Solutions
Let's examine common animation patterns and their accessible alternatives.
Parallax Scrolling
Problem: Background elements moving at different scroll speeds cause significant vestibular distress.
Solution:
.parallax-section {
background-attachment: fixed;
background-position: center;
}
@media (prefers-reduced-motion: reduce) {
.parallax-section {
background-attachment: scroll;
}
}Page Transitions
Problem: Full-page slide or zoom transitions during navigation.
Solution:
.page-transition-enter {
opacity: 0;
transform: translateX(100%);
}
.page-transition-enter-active {
opacity: 1;
transform: translateX(0);
transition: opacity 0.3s, transform 0.3s;
}
@media (prefers-reduced-motion: reduce) {
.page-transition-enter {
transform: none;
}
.page-transition-enter-active {
transition: opacity 0.15s;
}
}Scroll-Triggered Animations
Problem: Elements that animate into view as users scroll.
Solution:
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
if (prefersReducedMotion) {
// Instant reveal
entry.target.classList.add('visible');
} else {
// Animated reveal
entry.target.classList.add('animate-in');
}
}
});
});Hover Effects
Problem: Zoom, rotation, or complex hover animations.
Solution:
.card {
transition: transform 0.2s, box-shadow 0.2s;
}
.card:hover {
transform: translateY(-4px) scale(1.02);
box-shadow: 0 10px 30px rgba(0,0,0,0.15);
}
@media (prefers-reduced-motion: reduce) {
.card {
transition: box-shadow 0.2s;
}
.card:hover {
transform: none;
/* Keep subtle shadow change for feedback */
box-shadow: 0 4px 15px rgba(0,0,0,0.1);
}
}Providing User Controls
Beyond respecting system preferences, consider providing in-page animation controls for users who haven't configured OS-level settings.
Toggle Implementation
<button id="motion-toggle" aria-pressed="false">
Reduce Motion
</button>const motionToggle = document.getElementById('motion-toggle');
let reducedMotion = localStorage.getItem('reducedMotion') === 'true';
function applyMotionPreference() {
document.documentElement.classList.toggle('reduce-motion', reducedMotion);
motionToggle.setAttribute('aria-pressed', reducedMotion);
}
motionToggle.addEventListener('click', () => {
reducedMotion = !reducedMotion;
localStorage.setItem('reducedMotion', reducedMotion);
applyMotionPreference();
});
// Apply on load
applyMotionPreference();/* Respect both OS preference and user toggle */
@media (prefers-reduced-motion: reduce),
.reduce-motion {
* {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
}Testing for Compliance
Thorough testing ensures your implementation works across platforms and use cases.
Enable Reduced Motion in Operating Systems
macOS: System Preferences > Accessibility > Display > Reduce motion
Windows 11: Settings > Accessibility > Visual effects > Animation effects (toggle off)
iOS: Settings > Accessibility > Motion > Reduce Motion
Android: Settings > Accessibility > Remove animations
Testing Checklist
- Identify all animations: Document every motion effect on your site
- Classify essential vs. non-essential: Determine which animations are functional
- Test with reduced motion enabled: Verify all non-essential animations are disabled
- Test functionality preservation: Ensure essential animations still provide feedback
- Verify user controls: If provided, test the in-page toggle works correctly
- Cross-browser testing: Check Safari, Chrome, Firefox, and Edge
- User testing: Include users with vestibular disorders in testing when possible
Automated Testing Limitations
Most automated accessibility tools cannot fully evaluate WCAG 2.3.3 because:
- They can't distinguish essential from non-essential animation
- They can't easily detect motion triggered by interaction
- They may not simulate the `prefers-reduced-motion` state
Manual testing and code review remain essential for this criterion.
Common Implementation Mistakes
Avoid these frequent errors when implementing animation accessibility:
Mistake 1: Removing All Animation
Some developers disable ALL animation when reduced motion is preferred. This removes essential feedback and can harm usability.
Better approach: Replace motion with non-motion alternatives (opacity changes, color shifts) rather than removing feedback entirely.
Mistake 2: Ignoring CSS Animations
Developers sometimes address JavaScript-controlled animations but forget CSS animations and transitions.
Better approach: Audit all animation sources, including CSS keyframes, transitions, and JavaScript libraries.
Mistake 3: Not Testing the Toggle
If you provide an in-page motion toggle, ensure it persists across sessions and pages.
Better approach: Use localStorage or cookies to remember user preference site-wide.
Mistake 4: Assuming System Preference is Set
Many users don't know they can enable reduced motion at the OS level.
Better approach: Consider providing visible controls and consider a motion-safe default approach.
Framework-Specific Implementation
React
import { useReducedMotion } from 'framer-motion';
function AnimatedComponent() {
const shouldReduceMotion = useReducedMotion();
return (
<motion.div
initial={{ opacity: 0, y: shouldReduceMotion ? 0 : 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: shouldReduceMotion ? 0 : 0.3 }}
>
Content
</motion.div>
);
}Vue
<template>
<transition :name="prefersReducedMotion ? 'fade' : 'slide'">
<div v-if="show">Content</div>
</transition>
</template>
<script>
export default {
data() {
return {
prefersReducedMotion: window.matchMedia('(prefers-reduced-motion: reduce)').matches
}
}
}
</script>Frequently Asked Questions
What is the difference between WCAG 2.3.3 and 2.2.2?
WCAG 2.3.3 Animation from Interactions addresses motion triggered by user actions (clicking, scrolling, hovering) and is Level AAA. WCAG 2.2.2 Pause, Stop, Hide covers auto-playing animations that start automatically and is Level A. Both are important for motion-sensitive users but address different scenarios.
Is parallax scrolling allowed under WCAG 2.3.3?
Parallax scrolling is allowed if users can disable it. Since parallax is triggered by user scrolling (an interaction), it falls under 2.3.3. Implement a `prefers-reduced-motion` media query to provide a static alternative, and consider an in-page toggle for additional control.
Do loading spinners violate WCAG 2.3.3?
Loading spinners are generally considered essential animations because they communicate that a process is ongoing. Without this feedback, users might think the interface is frozen. However, consider using subtle, small-scale animations rather than full-screen spinning effects.
How do I test for WCAG 2.3.3 compliance?
Enable "Reduce motion" in your operating system's accessibility settings, then navigate your site and verify that non-essential animations are disabled or minimized. Test all interactive elements that trigger motion. Automated tools cannot fully test this criterion, so manual testing is required.
Is WCAG 2.3.3 legally required?
As a Level AAA criterion, WCAG 2.3.3 is not typically required by regulations like the ADA, Section 508, or EN 301 549, which generally reference Level AA. However, implementing motion controls is strongly recommended for user experience and may be required by specific organizational policies.
Can I use CSS-only solutions for WCAG 2.3.3?
Yes, the `prefers-reduced-motion` CSS media query handles most cases. However, JavaScript-controlled animations require JavaScript detection. A CSS-first approach using `@media (prefers-reduced-motion: no-preference)` to opt-in to animation is often the most robust solution.
Related Resources
- WCAG 2.2 Success Criteria List: Complete 87 Criteria Guide
- WCAG 2.4.11 Focus Appearance Minimum: Implementation Guide
- Understanding WCAG 2.2.2 Pause, Stop, Hide
- Accessible Animation Best Practices
- CSS prefers-reduced-motion Deep Dive
This article was crafted using a cyborg approach—human expertise enhanced by AI to provide accurate, comprehensive accessibility guidance based on the official W3C WCAG 2.2 specification at https://www.w3.org/TR/WCAG22/ and supporting documentation from WebAIM at https://webaim.org/.
Stay informed
Accessibility insights delivered
straight to your inbox.


Automate the software work for accessibility compliance, end-to-end.
Empowering businesses with seamless digital accessibility solutions—simple, inclusive, effective.
Book a Demo