interpolate-size

A property that lets sizing values without a fixed number — like `height: auto` — take part in transitions.

Also known as: Animate to height: autoAuto value transitions
···
html
<div class="wrap">
  <div class="badge" id="badge"><svg viewBox="0 0 10 10"><path id="bpath" d="M1.5 5.2l2.6 2.6L8.5 2.4" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"/></svg><span id="btext">확인 중</span></div>
  <button class="panel" id="panel">
    <div class="inner">첫 줄<br>둘째 줄<br>셋째 줄 — height:auto 로 트랜지션</div>
  </button>
</div>
css
:root{interpolate-size:allow-keywords}
.wrap{position:relative;width:min(240px,92%);display:grid;place-items:center}
.panel{width:100%;height:0;overflow:hidden;border:1px solid var(--line);border-radius:10px;background:var(--surface);
  transition:height .5s ease;padding:0;text-align:left}
.panel.open{height:auto}
.panel.fallback{transition:max-height .5s ease;max-height:0}
.panel.fallback.open{max-height:100px}
.inner{padding:12px 14px;font-size:11px;line-height:1.6;color:var(--fg)}
.badge{position:absolute;top:-30px;right:0;display:flex;align-items:center;gap:5px;padding:4px 9px;border-radius:999px;font-size:10px;font-weight:700;background:var(--bg);border:1px solid var(--line);color:var(--accent-3)}
.badge.no{color:var(--accent-2)}
.badge svg{width:9px;height:9px}
js
const ok = CSS.supports('interpolate-size', 'allow-keywords');
const b=document.getElementById('badge'),p=document.getElementById('bpath'),t=document.getElementById('btext');
b.classList.toggle('no', !ok);
p.setAttribute('d', ok ? 'M1.5 5.2l2.6 2.6L8.5 2.4' : 'M2 2l6 6M8 2l-6 6');
t.textContent = ok ? 'interpolate-size 지원됨' : '미지원 · max-height 폴백';
const panel = document.getElementById('panel');
if (!ok) panel.classList.add('fallback');
panel.classList.add('open');
setInterval(() => panel.classList.toggle('open'), 2200);

Transitioning from `height: 0` to `height: auto` has long been a CSS gap — the browser doesn't know how many pixels `auto` will resolve to before rendering, so it can't interpolate between them. Accordion expand animations have relied on faking it with a large `max-height`, the `grid-template-rows: 0fr↔1fr` trick, or measuring `scrollHeight` in JS.

Declaring `interpolate-size: allow-keywords` on `:root` lets the browser treat keyword values like `auto` as transitionable sizes. Then `height: 0 → height: auto` with plain `transition: height .3s` just works — regardless of how tall the actual content turns out to be.

Check caniuse/MDN baseline for support. Without it, the `grid-template-rows: 0fr`↔`1fr` trick (see the Accordion entry) or measuring `scrollHeight` in JS remain the standard fallbacks.

When to use

Animating an accordion or expandable panel with a real height transition, skipping the grid trick or JS measurement.