← Back to React Course | Chapter 11: Styling in React | Lesson 8 of 8

Animations with Framer Motion

An animation library like Framer Motion is like a choreographer for your UI — it plans out smooth, natural-looking movements instead of elements just snapping instantly from place to place.

Animating with motion Components

Framer Motion provides a motion.* version of every HTML tag (motion.div, motion.button, etc.) that accepts special animation props. Setting animate to a target style object smoothly transitions the element there from its current state.

Note: Swap a plain <div> for <motion.div> and it behaves exactly the same, just with extra animation props available.

Warning: It's an npm package requiring installation — motion.* components aren't available without importing from framer-motion first.

Example: Animating with motion Components

markup
// Run in your local React project (npm install required)
import { motion } from 'framer-motion';

function App() {
  return (
    <motion.div animate={{ x: 100 }} transition={{ duration: 1 }}>
      I slide to the right
    </motion.div>
  );
}

⚠️ This example uses an npm package with no CDN build available here — run this in your local React project.

Defining Initial and Animate States

The initial prop describes an element's starting appearance (like invisible and shifted up), and animate describes where it should end up. Framer Motion automatically interpolates smoothly between the two whenever the component mounts.

Note: A common entrance animation is initial={{ opacity: 0, y: -20 }} combined with animate={{ opacity: 1, y: 0 }}.

Warning: Without an initial prop, the element just appears in its final animate state instantly, with no entrance animation at all.

Example: Defining Initial and Animate States

markup
// Run in your local React project (npm install required)
import { motion } from 'framer-motion';

function FadeInBox() {
  return (
    <motion.div initial={{ opacity: 0 }} animate={{ opacity: 1 }} transition={{ duration: 0.5 }}>
      I fade in on mount
    </motion.div>
  );
}

⚠️ This example uses an npm package with no CDN build available here — run this in your local React project.

Animating Removal with AnimatePresence

Normally, when a component is removed from the React tree, it disappears instantly with no chance to animate out. Wrapping conditionally-rendered motion components in <AnimatePresence> lets you define an exit animation that plays before the element is actually removed from the DOM.

Note: AnimatePresence needs a stable key on the child it's animating, so it can track which specific element is entering or leaving.

Warning: Forgetting to wrap in AnimatePresence means the exit prop is simply ignored — the element vanishes instantly regardless of what exit animation you defined.

Example: Animating Removal with AnimatePresence

markup
// Run in your local React project (npm install required)
import { motion, AnimatePresence } from 'framer-motion';

function App() {
  const [show, setShow] = React.useState(true);
  return (
    <div>
      <button onClick={() => setShow(!show)}>Toggle</button>
      <AnimatePresence>
        {show && <motion.div key="box" exit={{ opacity: 0 }}>Fades out on remove</motion.div>}
      </AnimatePresence>
    </div>
  );
}

⚠️ This example uses an npm package with no CDN build available here — run this in your local React project.

Common Mistakes
  1. Using plain <div> instead of <motion.div> and expecting animation props like animate to work.
  2. Not providing an initial state, causing the first render to skip its entrance animation.
  3. Forgetting AnimatePresence is needed specifically for animating elements as they're REMOVED from the DOM, not just added.
Chapter Summary
  • Framer Motion is a popular animation library providing motion.* versions of every HTML element.
  • The initial, animate, and exit props describe an element's starting, target, and exit states.
  • AnimatePresence enables exit animations for elements being removed from the React tree.
  • Animations are declarative — you describe the states, not the frame-by-frame motion.
Browser Support

Requires npm install framer-motion — not available via CDN in this sandbox; works with React 16.8+.

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.