Skip to main content

Reduced Motion Checker

v1.0.0

Generate prefers-reduced-motion media-query checks — JS hook + CSS guards.

Reduced Motion CSS + React Hook
/* CSS: prefers-reduced-motion media query */
.animated {
  transform: var(--animation-value);
}

@media (prefers-reduced-motion: no-preference) {
  :root {
    --animation-value: /* your animation here */;
  }
}
@media (prefers-reduced-motion: reduce) {
  :root {
    --animation-value: none;
  }
  /* Global reset */
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

/* React hook */
import { useState, useEffect } from "react";

export function useReducedMotion(): boolean {
  const [reducedMotion, setReducedMotion] = useState(() => {
    if (typeof window === "undefined") return false;
    return window.matchMedia("(prefers-reduced-motion: reduce)").matches;
  });

  useEffect(() => {
    const mq = window.matchMedia("(prefers-reduced-motion: reduce)");
    const onChange = (e: MediaQueryListEvent) => setReducedMotion(e.matches);
    mq.addEventListener("change", onChange);
    return () => mq.removeEventListener("change", onChange);
  }, []);

  return reducedMotion;
}

// Usage:
const noMotion = useReducedMotion();
<motion.div animate={noMotion ? {} : { x: 100 }} />