Animations can transform a static interface into an engaging, delightful user experience. The right animations guide users' attention, provide feedback, and create a sense of polish that sets your application apart.
Well-crafted animations serve multiple purposes:
Framer Motion is a production-ready motion library for React with a simple, declarative API.
import { motion } from "framer-motion";
export default function AnimatedButton() {
return (
<motion.button
whileHover={{ scale: 1.1 }}
whileTap={{ scale: 0.9 }}
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
className="px-6 py-3 bg-blue-500 text-white rounded-lg"
>
Click me!
</motion.button>
);
}
Key Features:
A spring-physics based animation library that provides smooth, natural feeling animations.
import { useSpring, animated } from "@react-spring/web";
export default function SpringAnimation() {
const styles = useSpring({
from: { opacity: 0 },
to: { opacity: 1 },
});
return <animated.div style={styles}>I will fade in</animated.div>;
}
Manage component states over time, specifically designed for managing component mounting and unmounting.
import { CSSTransition, TransitionGroup } from "react-transition-group";
export default function ListTransition({ items }) {
return (
<TransitionGroup>
{items.map((item) => (
<CSSTransition key={item.id} timeout={500} classNames="item">
<div>{item.text}</div>
</CSSTransition>
))}
</TransitionGroup>
);
}
transform and opacity for better performancewill-change CSS property judiciouslyCreate cascading effects with staggered timing:
import { motion } from "framer-motion";
const container = {
hidden: { opacity: 1, scale: 0 },
visible: {
opacity: 1,
scale: 1,
transition: {
delayChildren: 0.3,
staggerChildren: 0.2,
},
},
};
const item = {
hidden: { y: 20, opacity: 0 },
visible: {
y: 0,
opacity: 1,
},
};
export default function StaggeredList({ items }) {
return (
<motion.ul variants={container} initial="hidden" animate="visible">
{items.map((text, index) => (
<motion.li key={index} variants={item}>
{text}
</motion.li>
))}
</motion.ul>
);
}
Create smooth transitions between routes:
import { AnimatePresence, motion } from "framer-motion";
import { useRouter } from "next/router";
export default function PageTransition({ children }) {
const router = useRouter();
return (
<AnimatePresence mode="wait">
<motion.div
key={router.route}
initial={{ opacity: 0, x: -200 }}
animate={{ opacity: 1, x: 0 }}
exit={{ opacity: 0, x: 200 }}
transition={{ duration: 0.3 }}
>
{children}
</motion.div>
</AnimatePresence>
);
}
Animation libraries for React have matured significantly, offering powerful tools to create engaging user experiences. Whether you choose the declarative approach of Framer Motion, the spring-physics of React Spring, or another solution, the key is to use animations purposefully to enhance your user interface.
Remember to prioritize performance, accessibility, and user experience over flashy effects. The best animations are often the ones users don't consciously notice but make the interface feel more responsive and polished.