Auto Height

A container that animates its height to fit its content whenever it changes.

Animate UI is a set of animated primitives for React, built with Motion.

"use client"

import * as React from "react"
import { AutoHeight } from "@animate-ui/react/primitives/effects/auto-height"
import { AnimatePresence, motion } from "motion/react"

import { Button } from "@/components/ui/button"

const SHORT =
  "Animate UI is a set of animated primitives for React, built with Motion."
const LONG = [
  "Animate UI is a set of animated primitives for React, built with Motion.",
  "Swap the import of your Radix UI, Base UI or React Aria primitives and your components animate, with exactly the same API.",
  "Its own primitives, like this one, cover the effects those libraries don't have.",
]

const swap = {
  initial: { opacity: 0, filter: "blur(4px)" },
  animate: { opacity: 1, filter: "blur(0px)" },
  exit: { opacity: 0, filter: "blur(4px)" },
  transition: { duration: 0.4, ease: "easeInOut" },
} as const

export default function AutoHeightDemo() {
  const [expanded, setExpanded] = React.useState(false)

  return (
    <div className="flex w-full max-w-sm flex-col items-start gap-4">
      <AutoHeight
        deps={[expanded]}
        className="w-full rounded-xl border bg-card p-4 text-sm"
      >
        <AnimatePresence mode="wait" initial={false}>
          {expanded ? (
            <motion.div key="long" className="flex flex-col gap-2" {...swap}>
              {LONG.map((paragraph) => (
                <p key={paragraph}>{paragraph}</p>
              ))}
            </motion.div>
          ) : (
            <motion.p key="short" {...swap}>
              {SHORT}
            </motion.p>
          )}
        </AnimatePresence>
      </AutoHeight>
      <Button
        variant="outline"
        size="sm"
        aria-expanded={expanded}
        onClick={() => setExpanded((value) => !value)}
      >
        {expanded ? "Show less" : "Show more"}
      </Button>
    </div>
  )
}

Installation

npm install @animate-ui/react motion
pnpm add @animate-ui/react motion
yarn add @animate-ui/react motion
bun add @animate-ui/react motion

Usage

import { AutoHeight } from '@animate-ui/react/primitives/effects/auto-height';

export function Details({ expanded }: { expanded: boolean }) {
  return (
    <AutoHeight deps={[expanded]}>
      {expanded ? <LongContent /> : <ShortContent />}
    </AutoHeight>
  );
}

The content is measured with a ResizeObserver, so the height also follows changes deps doesn't know about (fonts loading, images, a resized window). deps re-measures right away when your state changes.

Animation

  • The height springs to the content's height (stiffness 300, damping 30, no bounce), clipping the content while it moves.
  • With box-sizing: border-box (Tailwind's default), the container's padding and border are included in the measured height.
  • <AnimateUIProvider tempo> paces the default spring.
  • Under reduced motion, the height changes at once.

API Reference

AutoHeight

PropTypeDefault
asChild?
booleanfalse
deps?
React.DependencyList[]
transition?
Transition{ type: 'spring', stiffness: 300, damping: 30, bounce: 0, restDelta: 0.01 }
animate?
TargetAndTransition | LegacyAnimationControls-
children
React.ReactNode-
...props?
Omit<HTMLMotionProps<'div'>, 'animate'>-

Built by Skyleen. The source code is available on GitHub.

Last updated: 10/18/2026

On this page