Animations
Framer Motion patterns for delightful interactions.
Hover & Tap Effects
Subtle scale changes provide instant feedback on interactive elements.
Hover me
With rotate
Lift up
<motion.div
whileHover={{ scale: 1.02 }}
whileTap={{ scale: 0.98 }}
transition={{ type: "spring", stiffness: 400, damping: 25 }}
>
Interactive Element
</motion.div>Spring Physics
Spring animations feel natural and responsive.
Bouncy (damping: 10)
Balanced (damping: 25)
Snappy (damping: 30)
// Recommended spring settings
transition={{
type: "spring",
stiffness: 400,
damping: 25
}}Stagger Children
Animate lists with staggered delays for a polished feel.
const container = {
hidden: { opacity: 0 },
visible: {
opacity: 1,
transition: { staggerChildren: 0.1 },
},
}
const item = {
hidden: { opacity: 0, y: 20 },
visible: { opacity: 1, y: 0 },
}
<motion.div variants={container} initial="hidden" animate="visible">
{items.map(item => (
<motion.div key={item.id} variants={item} />
))}
</motion.div>Page Transitions
Smooth entrance animations for page content.
Page Content
Fades in and slides up on mount
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.3 }}
>
Page Content
</motion.div>Layout Animations
Use layout prop for smooth size transitions.
<motion.div layout>
{/* Content that changes size */}
</motion.div>
// For shared element transitions
<motion.div layoutId="shared-element">
{/* Will animate between states */}
</motion.div>Best Practices
Use spring animations
Springs feel more natural than linear or ease timing
Keep animations subtle
Scale between 0.98-1.02 for hover/tap effects
Respect reduced motion
Use useReducedMotion() hook for accessibility
Animate with viewport
Use whileInView with once: true for scroll animations