Animations (Framer Motion)
Smooth, accessible animation in React - Framer Motion for layout-driven motion, CSS transitions for the rest.
React animations
EXAMPLE
// npm install framer-motion
// 1. Mount and unmount animations
import { motion, AnimatePresence } from 'framer-motion';
function Toast({ show, message }: { show: boolean; message: string }) {
return (
<AnimatePresence>
{show && (
<motion.div
initial={{ opacity: 0, y: -20 }}
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0, y: -20 }}
transition={{ duration: 0.2 }}
className='fixed top-4 right-4 rounded bg-gray-900 text-white px-4 py-2'
>
{message}
</motion.div>
)}
</AnimatePresence>
);
}
// 2. Layout animations - free when items reorder
function List({ items }: { items: { id: string; name: string }[] }) {
return (
<ul>
{items.map((item) => (
<motion.li key={item.id} layout transition={{ duration: 0.18 }}>
{item.name}
</motion.li>
))}
</ul>
);
}
// 3. Drag with constraints
<motion.div drag dragConstraints={{ left: 0, right: 200 }} />
// 4. Variants for orchestration
const container = {
hidden: {},
show: { transition: { staggerChildren: 0.05 } },
};
const item = {
hidden: { opacity: 0, y: 8 },
show: { opacity: 1, y: 0 },
};
<motion.ul variants={container} initial='hidden' animate='show'>
{users.map((u) => (
<motion.li key={u.id} variants={item}>{u.name}</motion.li>
))}
</motion.ul>
// 5. Respect prefers-reduced-motion
import { useReducedMotion } from 'framer-motion';
function Hero() {
const reduce = useReducedMotion();
return (
<motion.h1
initial={reduce ? false : { opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
>
Welcome
</motion.h1>
);
}
// 6. Skip Framer for trivial CSS-only transitions
// className='transition transition-transform hover:scale-105'
Why it matters
Use Framer Motion when animations need to track layout, orchestrate, or feel physically right; use CSS transitions for hover/focus. Always respect prefers-reduced-motion - motion is not optional for accessibility.
Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.
Example
Example
import { motion } from 'framer-motion';
<motion.div animate={{ x: 100 }} transition={{ duration: 0.4 }} />
Try it Yourself »
Discussion
Loading…