Skip to content
Carl Victor Fontanos
Carl Victor Fontanos

Carl Victor Fontanos

Software Engineer

I build web applications and share what I learn along the way.

© 2026

Your Animations Might Be Making People Sick

C
Carlo Fontanos
· 2 min read

A colleague once told me she had to close my demo page because the scroll-triggered zoom effects made her dizzy - she has a vestibular disorder, and screen motion she didn't initiate triggers genuine nausea and disorientation. That group is not small, and every major OS ships a "reduce motion" setting for exactly this reason. Our job is to listen to it.

The CSS side

The blunt-but-effective global rule I ship in every project:

@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;
    }
}

Why 0.01ms instead of none? Because JavaScript listening for animationend / transitionend still fires - animations complete instantly rather than never, so UI that waits on them doesn't hang. That detail has saved me from reduced-motion-only bugs more than once.

The more surgical approach is opt-in per effect, and it reads nicely inverted:

@media (prefers-reduced-motion: no-preference) {
    .hero-img { animation: float 6s ease-in-out infinite; }
    html { scroll-behavior: smooth; }
}

Written this way, no motion preference = no fancy motion, and the animation is the enhancement. That's the right default posture.

The JavaScript side

const prefersReduced = matchMedia('(prefers-reduced-motion: reduce)');

function scrollToTop() {
    window.scrollTo({ top: 0, behavior: prefersReduced.matches ? 'auto' : 'smooth' });
}

prefersReduced.addEventListener('change', updateCarouselAutoplay);

The change listener matters: users toggle the OS setting live, and well-behaved pages respond without a reload. (More matchMedia patterns in this tutorial.) Autoplaying carousels, particle backgrounds, scroll-jacking - these should pause entirely under reduce.

What to reduce vs. remove

"Reduced" doesn't mean "dead interface". The consensus that's emerged:

  • Remove or minimize: parallax, zoom/scale transitions, auto-playing motion, anything that moves large areas or simulates depth. These are the vestibular triggers.
  • Fine to keep: instant state changes, opacity fades (crossfades don't trigger vestibular responses for most people), small color transitions. A 150ms opacity fade on a dropdown is fine; the dropdown flying in from off-screen is not.

Test it yourself: macOS Settings → Accessibility → Display → Reduce motion; Windows Settings → Accessibility → Visual effects → Animation effects off. Then browse your site. Ten minutes, and you'll know exactly where you stand - most sites fail within the first scroll.

C
Written by Carlo Fontanos

Full-stack web developer sharing practical tutorials and building tools that ship.

Got something on your mind?

My inbox is open - no forms disappearing into the void here.

  • Just say hello Found a tutorial useful? Spotted a mistake? Tell me.
  • Hire me for a project Have something custom in mind? Let's talk scope and timelines.
  • Product support Bought something here? I'll help you get it running.

I usually reply within 1-2 business days.

Message sent!

Your details are only used to reply to you.

Keep reading