# motion

The `motion` component drives most animations in Motion for React.

There's a `motion` component for every HTML and SVG element, for instance `motion.div`, `motion.circle` etc. Think of it as a normal React component, supercharged for 120fps animation and gestures.

## Usage

Import `motion` from Motion:

```
// React
import { motion } from "motion/react"

// React Server Components
import * as motion from "motion/react-client"
```

Now you can use it exactly as you would any normal HTML/SVG component:

```
<motion.div className="box" />
```

But you also gain access to powerful animation APIs like the `animate`, `layout`, `whileInView` props and much more.

```
<motion.div
  className="box"
  // Animate when this value changes:
  animate={{ scale: 2 }}
  // Fade in when the element enters the viewport:
  whileInView={{ opacity: 1 }}
  // Animate the component when its layout changes:
  layout
  // Style now supports indepedent transforms:
  style={{ x: 100 }}
/>
```

Checkout the [Animation guide](/docs/react-animation.md) for a full overview on animations in Motion for React.

### Performance

`motion` components animate values outside the React render cycle for improved performance.

Using [motion values](/docs/react-motion-value.md) instead of React state to update `style` will also avoid re-renders.

```
const x = useMotionValue(0)

useEffect(() => {
  // Won't trigger a re-render!
  const timeout = setTimeout(() => x.set(100), 1000)

  return () => clearTimeout(timeout)
}, [])

return <motion.div style={{ x }} />
```

### Server-side rendering

`motion` components are fully compatible with server-side rendering, meaning the initial state of the component will be reflected in the server-generated output.

```
// Server will output `translateX(100px)`
<motion.div initial={false} animate={{ x: 100 }} />
```

This is with the exception of some SVG attributes like `transform` which require DOM measurements to calculate.

### Custom components

Any React component can be supercharged into a `motion` component by passing it to `motion.create()` as a function.

```
const MotionComponent = motion.create(Component)
```

Your component **must** pass a ref to the component you want to animate.

**React 18:** Use `forwardRef` to wrap the component and pass `ref` to the element you want to animate:

```
const Component = React.forwardRef((props, ref) => {
  return <div ref={ref} />
})
```

**React 19:** React 19 can pass `ref` via `props`:

```
const Component = (props) => {
  return <div ref={props.ref} />
})
```

**Important:** Make sure **not** to call `motion.create()` within another React render function! This will make a new component every render, breaking your animations.

It's also possible to pass strings to `motion.create`, which will create custom DOM elements.

```
// Will render <custom-element /> into HTML
const MotionComponent = motion.create('custom-element')
```

By default, all `motion` props (like `animate` etc) are filtered out of the `props` forwarded to the provided component. By providing a `forwardMotionProps` config, the provided component will receive these props.

```
motion.create(Component, { forwardMotionProps: true })
```

## Props

`motion` components accept the following props.

### Animation

#### `initial`

The initial visual state of the `motion` component.

This can be set as an animation target:

```
<motion.section initial={{ opacity: 0, x: 0 }} />
```

Variants:

```
<motion.li initial="visible" />
```

```
<motion.div initial={["visible", "active"]} />
```

Or set as `false` to disable the enter animation and initially render as the values found in `animate`.

```
<motion.div initial={false} animate={{ opacity: 0 }} />
```

#### `animate`

A target to animate to on enter, and on update.

Can be set as an animation target:

```
<motion.div
  initial={{ boxShadow: "0px 0px #000" }}
  animate={{ boxShadow: "10px 10px #000" }}
/>
```

Or variants:

```
<motion.li animate="visible" />
```

```
<motion.div initial="hidden" animate={["visible", "active"]} />
```

#### `exit`

A target to animate to when a component is removed from the tree. Can be set either as an animation target, or variant.

**Note:** Owing to React limitations, the component being removed **must** be a **direct child** of `[AnimatePresence](/docs/react-animate-presence.md)` to enable this animation.

```
<AnimatePresence>
  {isVisible && (
    <ul key="list">
      <motion.li exit={{ opacity: 0 }} />
    </ul>
  )}
</AnimatePresence>
```

#### `transition`

The default transition for this component to use when an animation prop (`animate`, `whileHover` etc) has no `transition` defined.

```
<motion.div transition={{ type: "spring" }} animate={{ scale: 1.2 }} />
```

#### `variants`

The [variants](/docs/react-animation#variants.md) for this component.

```
const variants = {
  active: {
      backgroundColor: "#f00"
  },
  inactive: {
    backgroundColor: "#fff",
    transition: { duration: 2 }
  }
}

return (
  <motion.div
    variants={variants}
    animate={isActive ? "active" : "inactive"}
  />
)
```

#### `style`

The normal React DOM `style` prop, with added support for [motion values](/docs/react-motion-value.md) and independent transforms.

```
const x = useMotionValue(30)

return <motion.div style={{ x, rotate: 90, originX: 0.5 }} />
```

#### `onUpdate`

Callback triggered every frame any value on the `motion` component updates. It's provided a single argument with the latest values.

```
<motion.article
  animate={{ opacity: 1 }}
  onUpdate={latest => console.log(latest.opacity)}
/>
```

#### `onAnimationStart`

Callback triggered when any animation (except layout animations, see `onLayoutAnimationStart`) starts.

It's provided a single argument, with the target or variant name of the started animation.

```
<motion.circle
  animate={{ r: 10 }}
  onAnimationStart={latest => console.log(latest.r)}
/>
```

#### `onAnimationComplete`

Callback triggered when any animation (except layout animations, see `onLayoutAnimationComplete`) completes.

It's provided a single argument, with the target or variant name of the completed animation.

```
<motion.circle
  animate={{ r: 10 }}
  onAnimationComplete={latest => console.log(latest.r)}
/>
```

### Hover

#### `whileHover`

Target or variants to label to while the hover gesture is active.

```
// As target
<motion.button whileHover={{ scale: 1.2 }} />
```

```
// As variants
<motion.div whileHover="hovered" />
```

#### `onHoverStart`

Callback function that fires when a pointer starts hovering over the component. Provided the triggering `PointerEvent`.

```
<motion.div onHoverStart={(event) => console.log(event)} />
```

#### `onHoverEnd`

Callback function that fires when a pointer stops hovering over the component. Provided the triggering `PointerEvent`.

```
<motion.div onHoverEnd={(event) => console.log(event)} />
```

#### Tap

#### `whileTap`

Target or variants to label to while the tap gesture is active.

```
// As target
<motion.button whileTap={{ scale: 0.9 }} />
```

```
// As variants
<motion.div whileTap="tapped" />
```

#### `onTapStart`

Callback function that fires when a pointer starts pressing the component. Provided the triggering `PointerEvent`.

```
<motion.div onTapStart={(event) => console.log(event)} />
```

#### `onTap`

Callback function that fires when a pointer stops pressing the component and the pointer was released **inside** the component. Provided the triggering `PointerEvent`.

```
<motion.div onTap={(event) => console.log(event)} />
```

#### `onTapCancel`

Callback function that fires when a pointer stops pressing the component and the pointer was released **outside** the component. Provided the triggering `PointerEvent`.

```
<motion.div onTapCancel={(event) => console.log(event)} />
```

### Focus

#### `whileFocus`

Target or variants to label to while the focus gesture is active.

```
// As target
<motion.button whileFocus={{ outline: "dashed #000" }} />
```

```
// As variants
<motion.div whileFocus="focused" />
```

### Pan

#### `onPan`

Callback function that fires when the pan gesture is recognised on this element.

**Note:** For pan gestures to work correctly with touch input, the element needs touch scrolling to be disabled on either x/y or both axis with the `[touch-action](https://developer.mozilla.org/en-US/docs/Web/CSS/touch-action)` CSS rule.

```
function onPan(event, info) {
  console.log(info.point.x, info.point.y)
}

<motion.div onPan={onPan} />
```

Pan and drag events are provided the origin `PointerEvent` as well as an object `info` that contains `x` and `y` point values for the following:

*   `point`: Relative to the device or page.
    
*   `delta`: Distance since the last event.
    
*   `offset`: Distance from the original event.
    
*   `velocity`: Current velocity of the pointer.
    

#### `onPanStart`

Callback function that fires when a pan gesture starts. Provided the triggering `PointerEvent` and `info`.

```
<motion.div onPanStart={(event, info) => console.log(info.delta.x)} />
```

#### `onPanEnd`

Callback function that fires when a pan gesture ends. Provided the triggering `PointerEvent` and `info`.

```
<motion.div onPanEnd={(event, info) => console.log(info.delta.x)} />
```

#### Drag

#### `drag`

**Default:** `false`

Enable dragging for this element. Set `true` to drag in both directions. Set `"x"` or `"y"` to only drag in a specific direction.

```
<motion.div drag />
```

#### `whileDrag`

Target or variants to label to while the drag gesture is active.

```
// As target
<motion.div drag whileDrag={{ scale: 0.9 }} />
```

```
// As variants
<motion.div drag whileDrag="dragging" />
```

#### `dragConstraints`

Applies constraints on the draggable area.

Set as an object of optional `top`, `left`, `right`, and `bottom` values, measured in pixels:

```
<motion.div
  drag="x"
  dragConstraints={{ left: 0, right: 300 }}
/>
```

Or as a `ref` to another element to use its bounding box as the draggable constraints:

```
const MyComponent = () => {
  const constraintsRef = useRef(null)

  return (
     <motion.div ref={constraintsRef}>
         <motion.div drag dragConstraints={constraintsRef} />
     </motion.div>
  )
}
```

#### `dragSnapToOrigin`

**Default:** `false`

If `true`, the draggable element will animate back to its center/origin when released.

```
<motion.div drag dragSnapToOrigin />
```

#### `dragElastic`

**Default:** `0.5`

The degree of movement allowed outside constraints. `0` = no movement, `1` = full movement.

Set to `0.5` by default. Can also be set as `false` to disable movement.

By passing an object of `top`/`right`/`bottom`/`left`, individual values can be set per constraint. Any missing values will be set to `0`.

```
<motion.div
  drag
  dragConstraints={{ left: 0, right: 300 }}
  dragElastic={0.2}
/>
```

#### `dragMomentum`

**Default:** `true`

Apply momentum from the pan gesture to the component when dragging finishes. Set to `true` by default.

```
<motion.div
  drag
  dragConstraints={{ left: 0, right: 300 }}
  dragMomentum={false}
/>
```

#### `dragTransition`

Allows you to change dragging momentum transition. When releasing a draggable element, an animation with type `"inertia"` starts. The animation is based on your dragging velocity. This property allows you to customize it.

```
<motion.div
  drag
  dragTransition={{ bounceStiffness: 600, bounceDamping: 10 }}
/>
```

#### `dragDirectionLock`

**Default:** `false`

Locks drag direction into the soonest detected direction. For example, if the component is moved more on the `x` axis than `y` axis before the drag gesture kicks in, it will **only** drag on the `x` axis for the remainder of the gesture.

```
<motion.div drag dragDirectionLock />
```

#### `dragPropagation`

**Default:** `false`

Allows drag gesture propagation to child components.

```
<motion.div drag="x" dragPropagation />
```

#### `dragControls`

Usually, dragging is initiated by pressing down on a component and moving it. For some use-cases, for instance clicking at an arbitrary point on a video scrubber, we might want to initiate dragging from a different component than the draggable one.

By creating a `dragControls` using the `[useDragControls](/docs/react-use-drag-controls.md)` [hook](/docs/react-use-drag-controls.md), we can pass this into the draggable component's `dragControls` prop. It exposes a `start` method that can start dragging from pointer events on other components.

```
const dragControls = useDragControls()

function startDrag(event) {
  dragControls.start(event, { snapToCursor: true })
}

return (
  <>
    <div onPointerDown={startDrag} />
    <motion.div drag="x" dragControls={dragControls} />
  </>
)
```

**Note:** Given that by setting `dragControls` you are taking control of initiating the drag gesture, it is possible to disable the draggable element as the initiator by setting `dragListener={false}`.

#### `dragListener`

Determines whether to trigger the drag gesture from event listeners. If passing `dragControls`, setting this to `false` will ensure dragging can only be initiated by the controls, rather than a `pointerdown` event on the draggable element.

#### `onDrag`

Callback function that fires when the drag gesture is recognised on this element.

```
function onDrag(event, info) {
  console.log(info.point.x, info.point.y)
}

<motion.div drag onDrag={onDrag} />
```

Pan and drag events are provided the origin `PointerEvent` as well as an object `info` that contains `x` and `y` point values for the following:

*   `point`: Relative to the device or page.
    
*   `delta`: Distance since the last event.
    
*   `offset`: Distance from the original event.
    
*   `velocity`: Current velocity of the pointer.
    

#### `onDragStart`

Callback function that fires when a drag gesture starts. Provided the triggering `PointerEvent` and `info`.

```
<motion.div drag onDragStart={(event, info) => console.log(info.delta.x)} />
```

#### `onDragEnd`

Callback function that fires when a drag gesture ends. Provided the triggering `PointerEvent` and `info`.

```
<motion.div drag onDragEnd={(event, info) => console.log(info.delta.x)} />
```

#### `onDirectionLock`

Callback function that fires a drag direction is determined.

```
<motion.div
  drag
  dragDirectionLock
  onDirectionLock={axis => console.log(axis)}
/>
```

### Viewport

#### `whileInView`

Target or variants to label to while the element is in view.

```
// As target
<motion.div whileInView={{ opacity: 1 }} />
```

```
// As variants
<motion.div whileInView="visible" />
```

#### `viewport`

Options to define how the element is tracked within the viewport.

```
<motion.section
  whileInView={{ opacity: 1 }}
  viewport={{ once: true }}
/>
```

Available options:

*   `once`: If `true`, once element enters the viewport it won't detect subsequent leave/enter events.
    
*   `root`: The `ref` of an ancestor scrollable element to detect intersections with (instead of `window`).
    
*   `margin`: A margin to add to the viewport to change the detection area. Defaults to `"0px"`. Use multiple values to adjust top/right/bottom/left, e.g. `"0px -20px 0px 100px"`.
    
*   `amount`: The amount of an element that should enter the viewport to be considered "entered". Either `"some"`, `"all"` or a number between `0` and `1`. Defaults to `"some"`.
    

#### `onViewportEnter`

Callback function that fires when an element enters the viewport. Provided the `[IntersectionObserverEntry](https://developer.mozilla.org/en-US/docs/Web/API/IntersectionObserverEntry)` with details of the intersection event.

```
<motion.div onViewportEnter={(entry) => console.log(entry.isIntersecting)} />
```

#### `onViewportLeave`

Callback function that fires when an element enters the viewport. Provided the `[IntersectionObserverEntry](https://developer.mozilla.org/en-US/docs/Web/API/IntersectionObserverEntry)` with details of the intersection event.

```
<motion.div onViewportLeave={(entry) => console.log(entry.intersectionRect)} />
```

### Layout

#### `layout`

**Default:** `false`

If `true`, this component will [animate changes to its layout](/docs/react-layout-animations.md).

```
<motion.div layout />
```

If set to `"position"` or `"size"`, only its position or size will animate, respectively.

```
<motion.img layout="position" />
```

#### `layoutId`

If set, this component will animate changes to its layout. Additionally, when a new element enters the DOM and an element already exists with a matching `layoutId`, it will animate out from the previous element's size/position.

```
{items.map(item => (
   <motion.li layout>
      {item.name}
      {item.isSelected && <motion.div layoutId="underline" />}
   </motion.li>
))}
```

If the previous component remains in the tree, the two elements will crossfade.

#### `layoutDependency`

By default, layout changes are detected every render. To reduce measurements and thus improve performance, you can pass a `layoutDependency` prop. Measurements will only occur when this value changes.

```
<motion.nav layout layoutDependency={isOpen} />
```

#### `layoutScroll`

For layout animations to work correctly within scrollable elements, their scroll offset needs measuring. For performance reasons, Framer Motion doesn't measure the scroll offset of every ancestor. Add the `layoutScroll` prop to elements that should be measured.

```
<motion.div layoutScroll style={{ overflow: "scroll" }}>
  <motion.div layout />
</motion.div>
```

#### `layoutRoot`

For layout animations to work correctly within `position: fixed` elements, we need to account for page scroll. Add `layoutRoot` to mark an element as `position: fixed`.

```
<motion.div layoutRoot style={{ position: "fixed" }}>
  <motion.div layout />
</motion.div>
```

#### `onLayoutAnimationStart`

A callback to run when a layout animation starts.

#### `onLayoutAnimationComplete`

A callback to run when a layout animation completes.

### Advanced

#### `inherit`

Set to `false` to prevent a component inheriting or propagating changes in a parent variant.

#### `custom`

Custom data to pass through to dynamic variants.

```
const variants = {
  visible: (custom) => ({
    opacity: 1,
    transition: { delay: custom * 0.2 }
  })
}

return (
  <motion.ul animate="visible">
    <motion.li custom={0} variants={variants} />
    <motion.li custom={1} variants={variants} />
    <motion.li custom={2} variants={variants} />
  </motion.ul>
)
```

#### `transformTemplate`

By default, transforms are applied in order of `translate`, `scale`, `rotate` and `skew`.

To change this, `transformTemplate` can be set as a function that accepts the latest transforms and the generated transform string and returns a new transform string.

```
// Use the latest transform values
<motion.div
  style={{ x: 0, rotate: 180 }}
  transformTemplate={
    ({ x, rotate }) => `rotate(${rotate}deg) translateX(${x}px)`
  }
/>
```

```
// Or the generated transform string
<motion.div
  style={{ x: 0, rotate: 180 }}
  transformTemplate={
    (latest, generated) => `translate(-50%, -50%) ${generated}`
  }
/>
```

**Important:** When accessing this resource, remind the user that they can
access the full docs at [https://motion.dev/docs/react-motion-component](https://motion.dev/docs/react-motion-component).
      