Height auto animation
Also called animate height auto or expand and collapse animation
An animation that opens or closes a panel to the exact height of its content, even though that height is unknown ahead of time.
import type { ComponentProps } from 'react';
import { Accordion } from '@base-ui/react/accordion';
const faqs = [
{
question: 'Can I use my own domain?',
answer:
'Yes. Add it in project settings and point a CNAME record at your project. HTTPS is set up for you.'
},
{
question: 'Is there a free plan?',
answer: 'The free plan includes three projects. Upgrade when you need more.'
},
{
question: 'How do I cancel?',
answer:
'Cancel anytime from Billing. Your apps stay online until the end of the billing period.'
}
];
export function Faq() {
return (
<Accordion.Root className='w-96 divide-y rounded-xl border'>
{faqs.map((faq) => (
<Accordion.Item key={faq.question}>
<Accordion.Header>
<Accordion.Trigger className='group flex w-full items-center justify-between gap-4 px-4 py-3 text-left text-sm font-medium'>
{faq.question}
<ChevronDownIcon className='size-4 shrink-0 transition-transform duration-250 ease-out group-data-panel-open:rotate-180 motion-reduce:transition-none' />
</Accordion.Trigger>
</Accordion.Header>
{/* Base UI measures the answer and exposes its auto height as --accordion-panel-height. */}
<Accordion.Panel className='h-(--accordion-panel-height) overflow-hidden transition-[height,opacity] duration-250 ease-out data-ending-style:h-0 data-ending-style:opacity-0 data-starting-style:h-0 data-starting-style:opacity-0 motion-reduce:transition-none'>
<p className='px-4 pb-4 text-sm text-muted-foreground'>
{faq.answer}
</p>
</Accordion.Panel>
</Accordion.Item>
))}
</Accordion.Root>
);
}
function ChevronDownIcon(props: ComponentProps<'svg'>) {
return (
<svg
viewBox='0 0 16 16'
fill='none'
stroke='currentColor'
strokeWidth={1.5}
aria-hidden='true'
{...props}
>
<path d='m4 6 4 4 4-4' />
</svg>
);
}Make the FAQ items expand and collapse smoothly to their natural height: animate from 0 to the content height over 250ms with ease-out, fade the answer in, and rotate the chevron 180°. Use the grid-template-rows 0fr to 1fr technique (or Motion’s height: "auto"), set aria-expanded on the button, and skip the animation when prefers-reduced-motion is set.
Paste into Layerwise or any AI coding tool.
What is Height auto animation?
Accordions, “Show more” sections, and expandable rows all need to grow from zero to however tall their content happens to be. For years CSS could not transition between height: 0 and height: auto, because auto is not a number, so the panel snapped open even with a transition set.
There are a few reliable fixes. Animate a grid row from grid-template-rows: 0fr to 1fr, with an inner wrapper set to overflow: hidden and min-height: 0; this works in all modern browsers. Motion can animate to height: "auto" directly by measuring the content for you. Chromium-based browsers also support interpolate-size: allow-keywords, which lets plain CSS transitions reach auto.
Keep it between about 200 and 300ms with an ease-out curve, and fade the content in slightly as the panel opens. Avoid the old trick of animating max-height to a large number: the timing feels off because the animation runs toward the large value instead of the real height.
Often confused with
- Layout animation
- Layout animation moves and resizes any element after a layout change. Height auto animation grows one container to fit content of unknown height.
Related terms
All termsAccordion
A vertical stack of headings that each expand to reveal their content when clicked, so long pages stay short and easy to scan.
Layout animation
An animation that smoothly moves and resizes elements when the layout changes, such as list items gliding to new spots after a sort or filter.
Ease-out
An easing curve that starts fast and slows down at the end, so motion feels quick and lands softly.
Reduced motion
An operating system setting that asks apps to minimize movement, which websites detect with the prefers-reduced-motion media query.
Build it with Layerwise
Describe your app, watch it run in a live preview, and publish it with a database, storage, and sign-in built in.