Animations with Framer Motion

By the end of this lesson you'll animate React UIs declaratively with Framer Motion (now the motion package): the motion.div component, initial / animate / exit , the transition prop, variants, AnimatePresence , gestures like whileHover , and layout animations.

Learn Animations with Framer Motion in our free React course — an interactive lesson with worked examples, a practice exercise and a quick reference.

Part of the free React course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.

1. The motion component

Framer Motion (published today as the motion package, historically framer-motion ) gives you animatable versions of every element: motion.div , motion.button , motion.li , and so on. They accept animation props. The two essentials: initial (where the animation starts) and animate (where it ends). When animate changes later, the element re-animates automatically.

Under the hood the library interpolates each property from its initial value to its animate value over time. Run this to see that frame-by-frame for opacity — declaring two endpoints and letting the library fill the gap:

Your turn. Describe a "slide in from the left and fade in" entrance as the objects you'd hand to a motion component. Fill in the three blanks, then run it and check the output.

2. The transition prop — timing & springs

The transition prop controls how the animation plays. For a tween you set duration and ease (e.g. "easeInOut" ). For natural, physics-based motion you use a spring ( type: "spring" ) tuned with stiffness and damping . You can also add a delay or stagger children. Springs feel best for interactive UI; tweens are predictable for precise timing.

3. Variants — named, reusable states

Variants are named animation states (like hidden and visible ) defined once in an object, then referenced by string. They keep your JSX clean, and — powerfully — a parent's variant can cascade to its children , letting you staggerChildren so a list animates in one item at a time.

4. AnimatePresence & gestures

There's a catch with exit animations: when you remove an element from the tree, React unmounts it immediately , leaving no time to animate out. AnimatePresence solves this — wrap conditionally-rendered elements in it, give them an exit prop, and the library keeps them mounted just long enough to play the exit animation. Add gestures like whileHover and whileTap for interactive feedback.

The layout prop is one of Framer Motion's most magical features. Add layout to a motion component and any time its size or position changes between renders, the library smoothly animates the difference — no manual measuring.

Great for reordering lists, expanding cards, or moving an item between columns. Combine with layoutId to animate an element as it moves from one place in the tree to another (shared-element transitions).

Tip: animating transform and opacity (which Framer Motion prefers) is GPU-accelerated and stays smooth.

5. Declarative vs manual animation

You can animate with CSS keyframes or by manually tweaking styles in a requestAnimationFrame loop — but you have to write every keyframe, track timing, and handle cleanup, and exit animations are genuinely painful. Framer Motion is declarative : you describe the states ( initial , animate , exit ) and the library computes the frames, orchestrates enter/exit, and interrupts gracefully when values change mid-flight. Less code, fewer bugs, smoother results.

The library is now published as the motion package; framer-motion is the older name you'll still see widely. The component API ( motion.div , etc.) is the same.

React unmounts removed elements immediately. Wrap them in AnimatePresence and give them an exit prop so they animate out first.

Use a spring for natural, interactive motion (drags, hovers); use a tween with a fixed duration when you need exact, repeatable timing.

Yes — honor the user's reduced-motion preference with useReducedMotion() and avoid large or flashing motion that can trigger discomfort.

No blanks this time — just a brief. Write staggerStarts(count, step) that returns each child's start time when a list staggers in. Run it and check your output against the expected line in the comments.

Practice quiz

What is a motion component like motion.div?

  • An animatable version of an element that accepts animation props
  • A React hook
  • A CSS class
  • A plain div with no extra features

Answer: An animatable version of an element that accepts animation props. motion.div (and motion.button, motion.li, etc.) is an enhanced element that accepts props like initial, animate, and transition to animate it.

What does the initial prop define?

  • The hover state
  • The transition duration
  • The state the element animates FROM when it first mounts
  • The final state of the animation

Answer: The state the element animates FROM when it first mounts. initial sets the starting values; the element animates from initial toward the animate values on mount.

What does the animate prop define?

  • The exit animation
  • The target state the element animates TO
  • The easing curve
  • Whether animation is on or off

Answer: The target state the element animates TO. animate is the target the element animates toward; changes to it are also animated automatically.

Which prop controls how the animation plays (duration, easing, spring)?

  • timing
  • ease
  • motion
  • transition

Answer: transition. The transition prop configures duration, ease, type (tween or spring), delay, and other timing details.

What are variants used for?

  • Defining named sets of animation states you can reference by name
  • Importing the library
  • Styling with CSS classes
  • Lazy loading components

Answer: Defining named sets of animation states you can reference by name. Variants are named target objects (e.g. hidden/visible) you reference by name, and they can cascade to children.

Why do you need AnimatePresence?

  • To pause all animations
  • To animate elements as they are REMOVED from the tree (exit animations)
  • To detect hover
  • To animate elements when they ENTER

Answer: To animate elements as they are REMOVED from the tree (exit animations). React removes elements immediately, so AnimatePresence keeps them mounted long enough to run their exit animation.

Which prop animates an element while the user hovers over it?

  • hoverAnimate
  • animateHover
  • onHover
  • whileHover

Answer: whileHover. whileHover (and whileTap for press) animate to a target state for the duration of the gesture, then animate back.

What does adding the layout prop to a motion component do?

  • Adds a CSS grid
  • Locks the layout in place
  • Automatically animates the element smoothly when its size or position changes
  • Disables animation

Answer: Automatically animates the element smoothly when its size or position changes. The layout prop makes Framer Motion smoothly animate changes to an element's position and size between renders.

What kind of transition produces natural, physics-based motion?

  • A linear tween
  • A spring
  • A step function
  • An instant cut

Answer: A spring. A spring transition simulates physics (stiffness, damping) for natural-feeling motion, common for interactive UI.

What is the main advantage of Framer Motion over manual CSS/JS animation?

  • It is declarative: you describe states and it handles the transitions, including enter/exit
  • It is the only way to animate in React
  • It removes the need for any styling
  • It produces smaller bundles than no library

Answer: It is declarative: you describe states and it handles the transitions, including enter/exit. You declare the states (initial/animate/exit) and Framer Motion computes the in-between frames and orchestrates enter/exit, instead of manually writing keyframes and cleanup.