Articles


Framer Motion Guide

Master the art of animations in React with Framer Motion.




Getting Started

Install Framer Motion:

npm install framer-motion

Basic import and usage:

import { motion } from 'framer-motion';

function App() {
  return (
    <motion.div
      initial={{ opacity: 0 }}
      animate={{ opacity: 1 }}
      transition={{ duration: 0.5 }}
    >
      Hello Framer Motion!
    </motion.div>
  );
}

AnimatePresence

Use AnimatePresence for exit animations and conditional rendering:

import { AnimatePresence, motion } from 'framer-motion';

function App() {
  const [isVisible, setIsVisible] = useState(true);

  return (
    <AnimatePresence>
      {isVisible && (
        <motion.div
          initial={{ opacity: 0 }}
          animate={{ opacity: 1 }}
          exit={{ opacity: 0 }}
          transition={{ duration: 0.5 }}
        >
          I can fade in and out!
        </motion.div>
      )}
    </AnimatePresence>
  );
}

Basic Animations

The three main props for animations are initial, animate, and exit:

import { motion } from 'framer-motion';

function Box() {
  return (
    <motion.div
      initial={{ opacity: 0, scale: 0.5 }}
      animate={{ opacity: 1, scale: 1 }}
      exit={{ opacity: 0, scale: 0.5 }}
      transition={{ duration: 0.5, ease: "easeOut" }}
    >
      I fade and scale in!
    </motion.div>
  );
}

Variants

Define reusable animations with variants for cleaner code:

const boxVariants = {
  hidden: { 
    opacity: 0, 
    scale: 0.5,
    y: 25
  },
  visible: { 
    opacity: 1, 
    scale: 1,
    y: 0,
    transition: {
      duration: 0.6,
      ease: "easeOut"
    }
  },
  exit: {
    opacity: 0,
    scale: 0.5,
    transition: {
      duration: 0.3
    }
  }
};

function AnimatedBox() {
  return (
    <motion.div
      variants={boxVariants}
      initial="hidden"
      animate="visible"
      exit="exit"
    >
      Using variants for cleaner code!
    </motion.div>
  );
}

Stagger Animations

Create beautiful cascade effects with staggered animations:

const containerVariants = {
  hidden: {},
  visible: {
    transition: {
      staggerChildren: 0.1,
      delayChildren: 0.2
    }
  }
};

const itemVariants = {
  hidden: { opacity: 0, y: 20 },
  visible: { opacity: 1 , y: 0, filter: "blur(0px)"  }
};

function StaggeredList() {
  const items = ['Item 1', 'Item 2', 'Item 3', 'Item 4'];
  
  return (
    <motion.ul
      variants={containerVariants}
      initial="hidden"
      animate="visible"
    >
      {items.map((item, index) => (
        <motion.li
          key={index}
          variants={itemVariants}
        >
          {item}
        </motion.li>
      ))}
    </motion.ul>
  );
}

Hover and Tap Animations

Add interactive animations with whileHover and whileTap:

function InteractiveButton() {
  return (
    <motion.button
      whileHover={{ 
        scale: 1.05,
        boxShadow: "0 10px 25px rgba(0,0,0,0.15)"
      }}
      whileTap={{ scale: 0.95 }}
      transition={{ 
        type: "spring", 
        stiffness: 400, 
        damping: 10 
      }}
      className="px-6 py-3 bg-blue-500 text-white rounded-lg"
    >
      Click me!
    </motion.button>
  );
}

Advanced Animations

Spring animations for more natural movement:

const springConfig = {
  type: "spring",
  stiffness: 300,
  damping: 30
};

function SpringBox() {
  return (
    <motion.div
      initial={{ x: -100 }}
      animate={{ x: 0 }}
      transition={springConfig}
    >
      Natural spring movement!
    </motion.div>
  );
}

Keyframe Animations

Create complex animations with arrays (keyframes):

function PulsingCircle() {
  return (
    <motion.div
      animate={{
        scale: [1, 1.2, 1],
        backgroundColor: ["#ff0000", "#00ff00", "#0000ff", "#ff0000"]
      }}
      transition={{
        duration: 2,
        repeat: Infinity,
        ease: "easeInOut"
      }}
      className="w-20 h-20 rounded-full"
    />
  );
}

Layout Animations

Smooth layout changes with the layout prop:

function LayoutExample() {
  const [isExpanded, setIsExpanded] = useState(false);
  
  return (
    <motion.div
      layout
      onClick={() => setIsExpanded(!isExpanded)}
      className={`cursor-pointer bg-blue-500 text-white p-4 rounded-lg ${isExpanded ? 'w-80 h-40' : 'w-40 h-20'}`}
      transition={{ type: "spring", stiffness: 300, damping: 30 }}
    >
      Click to expand!
    </motion.div>
  );
}

Scroll-Triggered Animations

Use useInView hook for scroll-based animations:

import { useInView } from 'framer-motion';
import { useRef } from 'react';

function ScrollTriggered() {
  const ref = useRef(null);
  const isInView = useInView(ref, { once: true });
  
  return (
    <motion.div
      ref={ref}
      initial={{ opacity: 0 , y: 25, filter: "blur(10px)"  }}
      animate={isInView ? { opacity: 1 , y: 0, filter: "blur(0px)"  } : {}}
      transition={{ duration: 0.6, ease: "easeOut" }}
    >
      I animate when scrolled into view!
    </motion.div>
  );
}

Best Practices

  • Performance: Use transform properties (x, y, scale, rotate) for better performance
  • Accessibility: Respect prefers-reduced-motion media query
  • Variants: Use variants for complex animations and better organization
  • Springs: Prefer spring animations over duration-based for more natural feel
// Respect user preferences
const shouldReduceMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;

const variants = {
  hidden: { opacity: 0, y: shouldReduceMotion ? 0 : 20 },
  visible: { 
    opacity: 1, 
    y: 0,
    transition: {
      duration: shouldReduceMotion ? 0 : 0.6
    }
  }
};

Common Patterns

Here are some popular animation patterns you can use:

// Fade in up
const fadeInUp = {
  initial: { opacity: 0, y: 60 },
  animate: { opacity: 1 , y: 0, filter: "blur(0px)"  },
  transition: { duration: 0.6, ease: "easeOut" }
};

// Scale in
const scaleIn = {
  initial: { scale: 0, opacity: 0 },
  animate: { scale: 1, opacity: 1 },
  transition: { duration: 0.5, ease: "backOut" }
};

// Slide in from left
const slideInLeft = {
  initial: { x: -100, opacity: 0 },
  animate: { x: 0, opacity: 1 },
  transition: { duration: 0.6, ease: "easeOut" }
};

Framer Motion provides a powerful and intuitive API for creating smooth, performant animations in React. Start with simple animations and gradually explore more advanced features as you become comfortable with the library.