Animate Height

Animates a container's height when its content changes.

AnimateHeightFragment smoothly transitions the height of its content whenever the values in dependencies change — expanding a disclosure, swapping a message, adding a row. It renders no wrapper of its own: it reads its child through a Fragment ref and drives the child's own height transition.

The child must set height: var(--animate-height, auto) and a height transition — that CSS variable is what the component measures and animates. Anything without a height transition is left untouched. A height change is movement on screen, so use ease-in-out and keep it under 300ms, and turn the transition off under prefers-reduced-motion so the size changes at once.

Your API keys rotate on the first of each month.

<AnimateHeightFragment dependencies={[expanded]}>
<div
  className="overflow-hidden transition-[height] duration-200 ease-in-out motion-reduce:transition-none"
  style={{ height: 'var(--animate-height, auto)' }}
>
  <p>Your API keys rotate on the first of each month.</p>
  {expanded && <p>Rotation issues a new key and keeps the old one valid for 24 hours…</p>}
</div>
</AnimateHeightFragment>

When to use

Use AnimateHeightFragment when a container changes size in place — a disclosure opening, a message swapping, a row appearing — and a jump would read as a glitch.

Use something else when:

  • The content is still loading. Hold its space with Skeleton so there is no change to animate.
  • A row shows and hides its content on demand. Use Disclosure, which animates its own panel.
  • The content opens as its own surface. Popover and Dialog animate their own entrance and exit.

Usage

Do

List every value that changes the content in dependencies, the same way you would for a useEffect. The height is only measured when one of them changes.

Don't

Animate a height that has no fixed transition. Without transition: height on the child, the component skips it and nothing animates.

Props

PropTypeDefault
dependenciesrequiredTypeDependencyListDefault—

Accessibility

AnimateHeightFragment relies on React 19.3+ Fragment Refs to observe its child without adding a wrapper element, so the DOM structure and its semantics are unchanged. Because it only animates a CSS height, content stays in the accessibility tree throughout the transition.