Harrison Merrill - Practice Site

WDD 331R Advanced CSS - Postprocessing the Cascade
Color scheme

interpolate-size

Animating an element from a fixed height to auto has been impossible in CSS for decades. The browser cannot interpolate between a concrete value and a keyword it has not yet computed. interpolate-size: allow-keywords changes that, enabling smooth height transitions on accordions, disclosures, and any element that needs to expand to fit its content.


What is interpolate-size?

interpolate-size allows CSS to animate between a fixed height and height: auto, something that was impossible for decades, as the browser simply could not resolve size keywords to concrete values. Browsers had no midpoint to interpolate. Some developers used to animate max-height to a large arbitrary value as a workaround, but that caused the element to reach its final size before the transition ended, making the easing feel wrong, as well as clamping content if the max value was ever bypassed. That method is outdated. A javascript approach works, but adds overhead and complexity to something that should be handled by pure CSS.

How does interpolate-size work?

Setting interpolate-size: allow-keywords on :root opts the entire page into keyword interpolation. By adding that single line, the browser will treatt size keywords like auto, min, max, ect. as animatable endpoints. Applying it to :root is recommended, which can be done on your base elements.css file. Correct implementation typically looks like the following:


:root {
	interpolate-size: allow-keywords;
}

Usage Pattern

With interpolate-size: allow-keywords set on :root, a height transition set to auto works exactly as expected. The overflow: hidden is required to clip the content during transition, as without it the content would become suddenly fully visible during animation. This panel is intentionally broken, using overflow: visible; instead to demonstrate that failure.

Additionally, for accessibility, you should always opt-in to the users preferences for reducing-motion. A good format for a block of code utilizing interpolated transitions might look something like this:


.panel {
    height: 0;
    overflow: hidden;
    transition: height 0.35s ease;
}
details[open] .panel {
    height: auto;
}
@media (prefers-reduced-motion: reduce) {
    .panel {
        transition: none;
    }
}
Browser Support

This one intentionally doesn't work, showing what it looks like on a browser that doesn't support it. The interpolate-size progressive enhancement is fully supported in Edge and Chrome, but not yet supported in firefox or safari, but it should be treated as an easy addition that enhances HTML wherever its supported and works natively without JavaScript. In unsupported browsers, it fails gracefully, by just not animating. However, If you need it to animate anyway, you can force it to animate by using the following javascript:


if (!CSS.supports('interpolate-size', 'allow-keywords')) {
  document.querySelectorAll('details').forEach((details) => {
    const panel = details.querySelector('.panel');

    details.addEventListener('toggle', () => {
      panel.style.height = details.open
        ? panel.scrollHeight + 'px'
        : '0';
    });
  });
}