Animation Beginner

Smooth height auto animations without JavaScript

Animating to height: auto required JS to measure scrollHeight, set a fixed pixel height, then snap back to auto. interpolate-size: allow-keywords lets CSS transition directly to and from intrinsic sizes.

Modern
6 lines
1:root { interpolate-size: allow-keywords; }
2.accordion {
3  height: 0; overflow: hidden;
4  transition: height .3s ease;
5}
6.accordion.open { height: auto; }
Old 10 lines
1.accordion { overflow: hidden; }
2// JS: measure height, animate to px, then snap to auto
3function open(el) {
4  el.style.height = el.scrollHeight + 'px';
5  el.addEventListener('transitionend', () => {
6    el.style.height = 'auto';
7  }, { once: true });
8}
click to expand with height: auto animation

oklch(L C H) is a perceptually uniform color space. L is lightness, C is chroma (saturation), H is hue angle. Equal L values look equally bright regardless of hue.

HSL lightness is not perceptually uniform. Yellow at 50% L looks far brighter than blue at 50% L. oklch fixes this by modeling how human vision actually works.

oklch is supported in Chrome 111+, Firefox 113+, and Safari 15.4+. Over 90% global coverage.

interpolate-size: allow-keywords → height: auto animates
Interpolate size
Newly available Since 2024 69% global usage
129+
131+
18.2+
129+

Since 2024 this feature works across the latest devices and browser versions. This feature might not work in older devices or browsers.

No JS needed

No scrollHeight measurement, no transitionend listener, no pixel-to-auto snap.

Works with any keyword

Transitions to and from auto, min-content, max-content, and fit-content all work with one declaration.

Set it once

Declaring interpolate-size on :root unlocks keyword size transitions everywhere on the page.

Lines Saved
10 → 6
No JS height measurement
Old Approach
scrollHeight + JS
Measure, set px, then snap to auto
Modern Approach
interpolate-size
Transition to height: auto directly

How it works

height: auto isn't animatable because the browser can't interpolate between a fixed length and a keyword. The workaround was JavaScript: read scrollHeight to get the actual pixel height, set it as a fixed value, trigger the transition, then snap back to auto on transitionend.

interpolate-size: allow-keywords opts the browser into animating keyword sizes. Set it on :root once and transitions to height: auto, width: fit-content, and other intrinsic sizes work everywhere on the page. No JavaScript, no scrollHeight, no transitionend.

New CSS drops every month.

Get one old → modern comparison in your inbox every week.

ESC