transition.out

Normally the state being entered picks the transition. When hover ends, the element returns to animate with animate’s transition. transition.out lets a state set the transition its values use when they leave it for a lower-priority state instead.

<motion.div
  initial={{ scale: 0, transition: { out: { delay: 0.6 } } }}
  animate={{ scale: 1 }}
  whileHover={{ scale: 1.2, transition: { duration: 0.15, out: true } }}
/>
<motion.div
  initial={{ scale: 0, transition: { out: { delay: 0.6 } } }}
  animate={{ scale: 1 }}
  whileHover={{ scale: 1.2, transition: { duration: 0.15, out: true } }}
/>
mode · live running open
// transition-out
initial.out: mount only hover out: true

out: true

out: true reuses the state’s own transition on the way out, so hover end is as quick as hover start:

<motion.div
  animate={{ opacity: 0.5, transition: { duration: 1 } }}
  whileHover={{ opacity: 1, transition: { duration: 0.1, out: true } }}
/>
<motion.div
  animate={{ opacity: 0.5, transition: { duration: 1 } }}
  whileHover={{ opacity: 1, transition: { duration: 0.1, out: true } }}
/>

An out transition

An object is a separate transition for leaving:

<motion.div
  whileHover={{
    scale: 1.2,
    transition: { type: 'spring', out: { duration: 0.4, ease: 'easeOut' } }
  }}
/>
<motion.div
  whileHover={{
    scale: 1.2,
    transition: { type: 'spring', out: { duration: 0.4, ease: 'easeOut' } }
  }}
/>

out on initial

On initial, out is the transition of the mount animation only. It is used once: later changes to animate, and returns from hover or tap, use their own transitions. A mount delay no longer delays every hover end.

<motion.div
  initial={{ opacity: 0, transition: { out: { delay: 1 } } }}
  animate={{ opacity: 1 }}
/>
<motion.div
  initial={{ opacity: 0, transition: { out: { delay: 1 } } }}
  animate={{ opacity: 1 }}
/>

Variant children inherit their parent’s initial label, so they use the same out. Values that initial doesn’t change on mount aren’t affected.

Value-specific transitions

Like any transition, out can hold per-value overrides:

<motion.div
  whileHover={{
    opacity: 1,
    x: 10,
    transition: { out: { delay: 0.5, opacity: { duration: 0 } } }
  }}
/>
<motion.div
  whileHover={{
    opacity: 1,
    x: 10,
    transition: { out: { delay: 0.5, opacity: { duration: 0 } } }
  }}
/>

Lists of labels

With a list of variant labels, the last label that sets out applies to all of the list’s values, including values from labels without an out.

Setting only out

out is not a transition of its own. transition: { out: { … } } alone keeps the value’s default transition on the way in (a spring for x, scale and friends), and only changes the way out.

Exit

exit always uses exit’s own transition. An element that exits while hovered doesn’t leave with hover’s out.

SSR

The optimized appear animation follows the same rule as the mount animation: initial’s transition.out when set, otherwise animate’s own transition, otherwise the transition prop. The server-started animation and the hydrated runtime agree, so nothing jumps on hydration.

API Reference

type ValueTransition = {
  // ...
  out?: boolean | Transition
}
type ValueTransition = {
  // ...
  out?: boolean | Transition
}

initial and animate objects accept an inline transition (and transitionEnd) in their types.

Based on Motion’s transition.out (Motion 14.7, #1725).