Motion
Back to framer.com
DocumentationComponents
LayoutGroup
Motion
Back to framer.com
Design and publish your first free site today.
Getting started
  • Introduction
  • Examples
Animation
  • Overview
  • Layout
  • Gestures
  • Scroll
  • Transition
Components
  • motion
  • AnimatePresence
  • LayoutGroup
  • LazyMotion
  • MotionConfig
  • Reorder
Motion values
  • Overview
  • useMotionValueEvent
  • useMotionTemplate
  • useScroll
  • useSpring
  • useTime
  • useTransform
  • useVelocity
  • useWillChange
Utilities
  • animate
  • transform
  • useAnimationControls
  • useAnimationFrame
  • useDragControls
  • useInView
  • useReducedMotion
3D
  • Introduction
  • LayoutCamera
  • LayoutOrthographicCamera
  • MotionCanvas
Guides
  • Accessibility
  • Reduce bundle size
  • Upgrade guides
Community
  • GitHub
  • Discord

LayoutGroup

Group motion components that should perform layout animations together.

By default, motion components with a layout prop will attempt to detect and animate layout changes every time they commit a React render.

It might be the case that components in different trees affect each other's layout.

function ToggleContent({ header, content }) {
const [isOpen, setIsOpen] = useState(false)
return (
<motion.div
layout
onClick={() => setIsOpen(!isOpen)}
>
<motion.h2 layout>{header}</motion.h2>
{isOpen ? content : null}
</motion.div>
)
}
function App() {
return (
<>
<ToggleContent />
<ToggleContent />
</>
)
}

When the state of one of these ToggleContent components changes, its sibling won't rerender, so it won't perform a layout animation.

This can be fixed by grouping both components with LayoutGroup:

import { LayoutGroup } from "framer-motion"
function App() {
return (
<LayoutGroup>
<ToggleContent />
<ToggleContent />
</LayoutGroup>
)
}

Now, whenever one layout component within LayoutGroup detects and animates layout changes, they all do.

#Namespace layoutId

Components expecting to perform shared layout animations are provided a layoutId prop.

function Tab({ label, isSelected }) {
return (
<li>
{label}
{isSelected
? <motion.div layoutId="underline" />
: null}
</li>
)
}
function TabRow({ items }) {
return items.map(item => <Tab {...item} />)
}

layoutId is global, so if multiple instances of TabRow are rendered, only one with layoutId="underline" will render at a time.

To fix this, LayoutGroup can be provided an id prop that namespaces the layoutId for all components within it.

function App() {
return (
<LayoutGroup id="top5">
<TabRow />
</LayoutGroup>
<LayoutGroup id="latest">
<TabRow />
</LayoutGroup>
)
}
PreviousAnimatePresenceNextLazyMotion
On this page
  • Namespace layoutId

Copyright © 2022 Framer B.V.

  • Security
  • Terms of Service
  • Privacy Statement