--- name: framer-motion-layout description: Official Framer Motion skill for layout animations — shared layout transitions, layoutId, exit animations, AnimatePresence. Use when building shared element transitions, layout animations, reorderable lists, or when asking about Framer Motion layout, layoutId, or shared transitions. license: MIT --- # Framer Motion Layout Animations ## When to Use This Skill Apply when implementing shared element transitions, layout animations for reordering, or coordinated mount/unmount animations. When the user asks about Framer Motion layout animations, layoutId, or AnimatePresence. **Related skills:** For core animation use **framer-motion-core**; for variants use **framer-motion-variants**; for React integration use **framer-motion-react**. ## Layout Prop The `layout` prop enables automatic position animations when layout changes: ```jsx {items.map(item => ( ))} ``` ### Layout Modes | Mode | Behavior | |------|----------| | `true` | Animate position and size | | `"position"` | Animate only position | | `"size"` | Animate only size | ```jsx ``` ## layoutId for Shared Element Transitions `layoutId` enables smooth transitions between elements in different components: ### Page Transitions ```jsx // Page A function CardA() { return ; } // Page B function CardB() { return ; } ``` When CardA unmounts and CardB mounts with the same `layoutId`, Framer Motion animates the element smoothly between positions. ### Modal Overlays ```jsx function ListItem({ item, onClick }) { return ( {item.name} ); } function Modal({ item }) { return (

{item.name}

{item.description}

); } ``` ## AnimatePresence for Layout AnimatePresence enables exit animations: ```jsx import { AnimatePresence, motion } from "framer-motion"; function TodoList({ todos }) { return ( {todos.map(todo => ( ))} ); } ``` ### AnimatePresence Modes ```jsx {isOpen && } ``` | Mode | Description | |------|-------------| | `"sync"` | All animations run simultaneously (default) | | `"wait"` | Exit completes before enter starts | | `"popLayout"` | Exiting element removed from layout immediately | ## Reorderable Lists Combine layout with drag for reorderable lists: ```jsx function ReorderableList({ items, setItems }) { return ( {items.map(item => ( { // Calculate new index and update }} initial={{ opacity: 0, scale: 0.8 }} animate={{ opacity: 1, scale: 1 }} exit={{ opacity: 0, scale: 0.8 }} /> ))} ); } ``` ## Shared Layout with Grid ```jsx function Grid({ items }) { return ( {items.map(item => ( ))} ); } ``` ## Exit Animations Elements must have exit states for AnimatePresence: ```jsx ``` ### Exit with layout ```jsx ``` ## Crossfade with layoutId When multiple elements share a layoutId at the same level: ```jsx function Toggle() { const [showA, setShowA] = useState(true); return ( {showA ? ( ) : ( )} ); } ``` The element smoothly morphs between states including border radius. ## Best practices - ✅ Use **layoutId** for shared element transitions between routes/pages. - ✅ Wrap animated lists with **AnimatePresence** for exit animations. - ✅ Use **layout** prop for automatic position animations. - ✅ Use **AnimatePresence mode="popLayout"** for smooth reordering. - ✅ Define **exit** states for components using AnimatePresence. - ✅ Use **layout** on parent containers when children need to animate position. ## Do Not - ❌ Forget to wrap conditionally rendered animated components with AnimatePresence. - ❌ Use the same layoutId on multiple elements at the same level. - ❌ Forget to define exit states for components that unmount. - ❌ Use layout animations without proper keys on children. - ❌ Animate too many layout elements simultaneously — group or stagger. ### Learn More https://www.framer.com/motion/layout-animations/ https://www.framer.com/motion/animate-presence/