Animating to auto is one of those CSS features every frontend developer tries. The typical use-case is an expanding box which animates from a fixed height of, say, 20px to the height of it's content -- or auto. Any attempt results in frustration because the animation won't work.
Of course, the browser knows the actual height of the box, but mathematically interpolating 20px to auto is not possible in CSS. Until now.
The interpolate-size CSS property
The new interpolate-size: allow-keywords; CSS property enables resizing between any intrinsic size value such as auto, fit-content, min-content, or max-content. The following demonstration shows the default behaviour, but clicking the checkbox enables a smooth animation:
<iframe src="./demo.html" width="600" height="600"></iframe>
The essential CSS:
div {
block-size: 4lh;
overflow: clip;
interpolate-size: allow-keywords;
transition: block-size 1s ease-in-out;
}
div:hover {
block-size: auto;
}
interpolate-size: allow-keywords; is available in Chromium-based browsers including Chrome, Edge, Opera, Vivaldi, and Brave. It's coming to other browsers but this is a perfect example of progressive enhancement: without support, the box still expands -- it just won't be animated.
By default, the browser applies the standard non-animating behaviour interpolate-size: numeric-only; to all elements. You can apply interpolate-size: allow-keywords; to specific elements or all elements with:
:root {
interpolate-size: allow-keywords;
}
The calc-size() CSS function
Sometimes, animating to auto is not quite what you need. Assume you want to animate to half the box's height. The following CSS won't work because calc() does not support intrinsic size keywords such as auto:
/* FAILS! */
div:hover {
block-size: calc( auto / 2 );
}
The calc-size() function fixes the problem:
/* WORKS! */
div:hover {
block-size: calc-size( auto, size / 2 );
}
You pass it two parameters:
- a value -- typically an intrinsic size keyword such as
auto, and - an expression calculation where
sizedenotes the value passed.
Other examples:
/* auto plus an extra 2em */
block-size: calc-size( auto, size + 2em );
/* auto rounded up to nearest 50px */
block-size: calc-size( auto, round(up, size, 50px) );
Again, calc-size() is only available in Chromium-based browsers at this time. Other browsers won't parse the function so ensure you define a fallback:
div:hover {
/* fallback size */
block-size: auto;
/* larger size where supported */
block-size: calc-size( auto, size + 2em );
}
Documentation
For more information, refer to MDN: