"Your animations feel fake because nothing in the real world takes exactly 300ms to move."
In the real world, things have mass. They have friction. They have momentum.
Framer Motion ignores "duration" effectively. It uses Spring Physics.
You don't say "move in 0.5s". You say "move with 300 stiffness and 20 damping". The result is UI that feels tangible, responsive, and alive.
02. Layout Magic (The "Wow" Factor)
This is Framer Motion's superpower.
Add the layout prop, and the component will automatically animate to its new position when the DOM layout changes (e.g., list reordering, sorting, or when an element is removed).
It effectively snapshots the start and end layout, and FLIPs (First, Last, Invert, Play) between them efficiently.
// ❌ The Hard Way (CSS)
// Calculate positions, use transforms, hope for the best...
// ✅ The Framer Way
<motion.div layout>
{/* I will slide to my new home automatically, no matter what happens around me */}
</motion.div>
03. Gestures & Physics
Drag, hover, tap, focus. Framer Motion handles the physics of interaction, allowing you to "throw" elements. When you release a dragged element, it doesn't just stop. It carries its momentum (velocity) and decelerates naturally using physics.
The Power of `whileHover`
CSS :hover is instant and jerky. Framer's whileHover animates to the state using your spring physics.
<motion.button
whileHover={{ scale: 1.05 }}
whileTap={{ scale: 0.95 }}
/>
04. Orchestration (Stagger)
Animating lists doesn't mean adding a delay to every single item `delay: index * 0.1`. Framer Motion introduces Variants to handle this elegantly. Parent variants orchestrate children.
const list = {
hidden: { opacity: 0 },
show: {
opacity: 1,
transition: {
staggerChildren: 0.1 // 👈 The magic line
}
}
}
const item = {
hidden: { y: 20, opacity: 0 },
show: { y: 0, opacity: 1 }
}
06. Physics Playground
Tweak the spring physics and interact with the boxes below. Notice how changing Stiffness and Damping alters the "feel" of the UI completely.
Feature Drag Constraints
The box below is constrained to its container. Try throwing it against the wall! Framer calculates the momentum and bounces it back.