How do you make website animation accessible?
You make website animation accessible by giving people control over motion and making sure no animation is required to use the page. In practice that means four things: honor the prefers-reduced-motion setting, add pause controls to anything that keeps moving, avoid flashing, and never let content depend on an animation finishing. Done well, most visitors won't notice the difference, and the ones who need it will.
Accessible animation sits where two topics meet: motion design and accessibility law. The legal background is in our hub on website accessibility compliance. The motion side, including when animation helps conversion at all, is covered in motion design for marketing websites. This guide is the implementation bridge between them.
Who is affected by motion on websites?
Motion affects people with vestibular disorders most directly: large parallax, zooming and spinning effects can cause dizziness, nausea and headaches that last well after they leave the page. It also affects people with attention-related disabilities, who find constant movement distracting, and people with photosensitive epilepsy, for whom fast flashing can trigger seizures.
WCAG criterion | Level | What it asks |
|---|---|---|
2.2.2 Pause, Stop, Hide | A | Moving, blinking or auto-updating content that lasts over five seconds can be paused or hidden |
2.3.1 Three Flashes or Below Threshold | A | Nothing flashes more than three times in any one second |
2.3.3 Animation from Interactions | AAA | Motion triggered by interaction can be turned off unless essential |
2.4.11 Focus Not Obscured | AA | Animated sticky headers and banners can't hide keyboard focus |
Animation from interactions is AAA, so it isn't strictly required for AA conformance. We still treat respecting reduced motion as standard practice: it's cheap to implement, operating systems already expose the setting, and ignoring it is the kind of thing users notice. Our WCAG 2.2 checklist lists the rest of the AA criteria.
What is prefers-reduced-motion?
prefers-reduced-motion is a CSS media feature that tells your website whether the visitor has asked their operating system to minimize motion. It has two values: no-preference and reduce. Browsers read it from system settings like Reduce motion on macOS and iOS, Animation effects on Windows and Remove animations on Android. MDN's prefers-reduced-motion reference documents it.
Because the setting lives in the operating system, a visitor who needs it sets it once and expects every site to respect it. You don't need a toggle on your site, though offering one is a nice extra for people who don't know the system setting exists. CSS and JavaScript can both read the preference, which means it works for plain CSS transitions and for animation libraries.
How do you implement reduced motion in CSS?
In CSS, the cleanest approach is to make motion opt-in: put large animations inside a media query for prefers-reduced-motion: no-preference, so visitors who chose reduce simply never get them. The alternative is to write your animations normally and override them inside a prefers-reduced-motion: reduce query, shortening or replacing them.
- Opt-in for big motion. Wrap parallax, slide-ins, zooms and scroll-driven animations in the no-preference query.
- Override for everything else. Under the reduce query, change transforms to opacity fades and shorten durations.
- Keep state changes. Hover colors, focus rings and accordion openings should still work, just without large movement.
- Turn off smooth scroll behavior. If you set scroll-behavior to smooth for anchor links, set it back to auto under reduce.
- Pause CSS loops. Infinite animations, like marquees or rotating badges, should stop or offer a pause.
Avoid a blanket rule that sets every animation and transition duration to almost zero under reduce. It's a common snippet, but it can break components that rely on transition events and it removes useful feedback along with harmful motion.
How do you handle reduced motion in GSAP, Motion and Lenis?
Animation libraries can read the same preference, and each has a tidy way to do it. Handle it at the library level rather than animation by animation, so new animations inherit the behavior. Our comparison of GSAP vs Motion vs CSS covers when to use which library.
- GSAP. Use gsap.matchMedia() with two conditions, one for no-preference and one for reduce. Build full ScrollTrigger timelines in the first, and simple opacity fades in the second. matchMedia also reverts animations automatically when the setting changes.
- Motion (formerly Framer Motion). Set reducedMotion to user on a MotionConfig wrapper, and Motion will skip transform and layout animations for visitors who chose reduce while keeping opacity changes. The useReducedMotion hook lets you change specific animations by hand.
- Lenis smooth scroll. Check the preference before you start Lenis, and don't initialize it if reduce is set. Smooth-scroll libraries change how scrolling feels, which is exactly what many reduced-motion users want to avoid.
- Lottie and video. Don't autoplay looping Lottie files or background videos for reduce users; show the first frame or a poster image with a play control.
How a reduced-motion setup works in a GSAP scroll section
For example, suppose a homepage has a pinned section where product screenshots slide and scale as you scroll. Inside gsap.matchMedia, the no-preference branch creates the pinned ScrollTrigger timeline with the slide and scale tweens.
The reduce branch creates no pin and no scrub. Each screenshot simply fades in when it enters the viewport, and the text is in the normal reading order. Both branches end with the same content visible.
Because matchMedia cleans up the branch that no longer applies, a visitor who toggles the system setting mid-visit gets the right version after the next change, without a reload. It's a few lines more than the single timeline, and it's the same pattern we'd use in any build.
What should reduced-motion animation look like?
Reduced-motion animation should keep the meaning of each animation and drop the movement. If a card slides in to show it's new, a fade does the same job. If a number counts up, show the final number. If a section pins and scrubs, let it scroll normally.
Effect | Default version | Reduced-motion version |
|---|---|---|
Scroll reveal | Slide up 40px and fade in | Fade in only, or appear instantly |
Parallax background | Moves at a different speed | Static image |
Pinned scroll story | Pinned and scrubbed timeline | Normal scrolling with fades |
Page transition | Slide or zoom between pages | Short crossfade |
Logo marquee | Infinite horizontal scroll | Static row or grid |
Hero video | Autoplaying loop | Poster image with play button |
Count-up numbers | Animated from zero | Final value shown |
Landing pages are where teams are tempted to keep heavy motion for everyone. Our article on landing page animation looks at whether it helps conversion, and the same reduced-motion versions apply to animated product demos.
How do you audit and fix animation on an existing site?
Audit animation by browsing your site twice, once normally and once with reduce turned on in your operating system, and listing every effect that moves, loops or flashes. Then fix them in priority order: flashing first, then anything that can't be paused, then large motion that ignores the setting.
Turn on reduced motion
Set Reduce motion in macOS or iOS settings, or turn off Animation effects in Windows. Reload your site.
List every moving element
Scroll reveals, parallax, carousels, marquees, videos, Lottie files, page transitions, smooth scroll.
Check for flashing
Anything flashing quickly, especially in video or hero effects, gets fixed first.
Add pause controls
Carousels, marquees and background video that run longer than five seconds need a visible pause button reachable by keyboard.
Branch the big effects
Add reduce versions in CSS or your animation library, as above.
Check content without JavaScript animation
Make sure nothing is invisible until a script reveals it. If the script fails, the content should still show.
Recheck performance
Heavy animation also hurts responsiveness. See scroll animations without killing performance.
Accessible animation and fast pages go together: fewer heavy effects for reduce users and careful motion for everyone keep interaction responsive, as our guide to fast landing pages explains.
