CSS Interpolate-Size Table

PieceWhat it doesField note
:root { interpolate-size: allow-keywords }Opt in page-wideOne line unlocks height:auto animations - 20-year wish granted
transition: height 0.3sNow works to autoWith the opt-in, keyword sizes are interpolable lengths
calc-size()Auto-aware mathcalc-size(auto, size + 20px) - calc that sees intrinsic sizes
height: auto to fixedThe accordionopen state height:auto + transition = JS-free accordions
Progressive enhancementNo opt = instant jumpBrowsers without it just snap - the fallback IS the old behavior
Performance: layout-boundHeight anims reflowEvery frame relayouts - fine for small UI, not long lists
Details/summary pairingThe classic casedetails[open] height transitions - pairs with the toggle event
Grid track animation1fr to auto comingSame family: keyword interpolation reaching grid tracks
Reference: the MDN interpolate-size reference. interpolate-size: allow-keywords grants the 20-year wish: TRANSITIONING TO height: auto (and other keyword sizes) now interpolates - accordions, disclosures and expanding panels animate open without JavaScript measuring scrollHeight. The mechanism: the opt-in teaches the browser to treat keyword sizes as interpolable lengths, and calc-size() extends calc to see intrinsic sizes (auto plus 20px). Bottom line: it is opt-in per page because it changes what animates, browsers without it simply SNAP (the fallback IS the old behavior - progressive enhancement for free), and height animations still reflow every frame - right for small UI, wrong for long lists. Related tools: details table (the classic accordion), animations table (the transitions being extended), and text-wrap table (balance on the lines being revealed).

interpolate-size: allow-keywords grants the twenty-year wish: TRANSITIONING TO height: auto (and other keyword sizes) now interpolates - accordions, disclosures and expanding panels animate open without JavaScript measuring scrollHeight and hard-coding pixel heights.

Bottom line: the mechanism is an opt-in that teaches the browser to treat keyword sizes as interpolable lengths, and calc-size() extends calc to see intrinsic sizes (auto plus 20px). The opt-in design makes adoption free: browsers without support simply SNAP open - the fallback IS the old behavior.

The honest part: height animations reflow every frame - each intermediate height is a real layout pass. That is fine for accordions and menus (a few hundred pixels of subtree), wrong for long lists; the compositor-friendly transforms from the transform table remain the animation default for anything large.

How to use

  1. Opt in once: :root { interpolate-size: allow-keywords; } - every keyword-size transition on the page starts interpolating.
  2. Animate the accordion: details[open] .content { height: auto; } with a transition on height - pair with the toggle event for enter/exit asymmetry.
  3. Compute against intrinsic: width: calc-size(auto, size + 20px) - calc that reads the content's own size instead of a guessed constant.

Frequently asked questions

Why couldn't CSS transition to height: auto for twenty years?

Interpolation needs numeric endpoints. A transition computes intermediate values between a start and end - 100px to 300px is arithmetic. But auto is not a number: it means 'whatever the content requires', a value the engine resolves during layout. Transitioning to it meant either running layout for every hypothetical height (expensive) or guessing. The allow-keywords opt-in accepts the cost: the browser interpolates using the intrinsic size as the endpoint, re-resolving as content changes mid-animation. It is opt-in per PAGE (not per property) precisely because it changes what animations cost - the default stays snap-cheap.

What does calc-size() add over regular calc()?

Visibility into intrinsic sizes. Regular calc() only does arithmetic on concrete lengths - auto inside calc is invalid. calc-size(auto, size + 20px) treats the intrinsic size as a value: 'the content's own height, plus 20 pixels'. The practical uses: padded auto-animations (animate to auto plus breathing room), minimum-content-aware widths, and combining measured content with fixed offsets in one declaration without JavaScript measurement. It pairs with the interpolate-size opt-in - both exist because keyword sizes became first-class animation participants, and the arithmetic layer needed to catch up.

How do I build the JS-free accordion with details and interpolate-size?

The pieces: :root { interpolate-size: allow-keywords }, details .content wrapped in a container whose height transitions, and details[open] setting that container's height to auto. Closed state is height: 0 with overflow hidden; the open state's auto resolves against real content, and the transition animates between them - the JS-free accordion that used to require scrollHeight measurement plus resize observers for dynamic content. The toggle event still earns its place for the close animation (CSS transitions need a concrete end state, and closing to 0 works while the content is still in the DOM) and for lazy-rendering expensive bodies. The result degrades to instant snap-open on non-supporting browsers - the accordion still works everywhere.

What is the performance contract of animating height?

Reflow per frame, by definition. Height is a layout property: every intermediate value is a real layout pass over the element's subtree - fine for an accordion (a small subtree, 300ms), a jank source for animating a page-long list or a grid of hundreds of items. The rules: keep keyword-size animations to small UI (menus, accordions, disclosure panels), prefer transform-based animation (scaleY, grid-template tricks) when the element is large or the animation is long, and measure on low-end hardware. The interpolate-size feature makes the animation POSSIBLE in CSS; the transform-vs-layout decision from the animation table still governs whether it is SMOOTH.

Related tools