CSS interpolate-size allows transitions and animations to work with intrinsic sizing keywords such as auto, min-content, max-content, and fit-content in supported browsers.
This solves a long-standing limitation in CSS. Traditionally, a transition could animate between two numeric lengths, but it could not smoothly interpolate between a fixed value such as 0px and an intrinsic size such as height: auto.
interpolate-size Syntax
:root {
interpolate-size: allow-keywords;
}
The property has two main values:
- numeric-only keeps the traditional behavior and does not allow interpolation with intrinsic sizing keywords.
- allow-keywords allows a supported intrinsic sizing keyword to interpolate with a length or percentage.
interpolate-size is inherited. Setting it on :root can opt the whole page into intrinsic-size interpolation when that is appropriate for your design.
Animate Height to auto
The following demo transitions a panel between height: 0 and its natural height. The browser can interpolate the auto value because interpolate-size is enabled.
Example:
<div class="card" id="card">
<button id="toggle">Toggle details</button>
<div class="details">
<p>This panel transitions to its intrinsic auto height.</p>
</div>
</div>
<style>
:root {
interpolate-size: allow-keywords;
}
.details {
height: 0;
overflow: clip;
transition: height 0.4s ease;
}
.card.open .details {
height: auto;
}
</style>
Why Intrinsic Sizes Were Difficult to Animate
Values such as auto and max-content depend on layout. Their final numeric size is calculated from content and surrounding constraints. Older interpolation rules did not treat those keywords as numeric endpoints, so a transition between 0 and auto jumped directly instead of animating.
interpolate-size changes that behavior for supported cases. The browser treats the intrinsic keyword in a way that can participate in interpolation with a numeric size.
Use calc-size() for More Control
The related calc-size() function lets you perform calculations using one intrinsic sizing basis. The special size keyword represents the resolved intrinsic size inside the calculation.
Example:
.menu-label {
width: 80px;
overflow: clip;
transition: width 0.35s ease;
}
.menu-label:hover {
width: calc-size(max-content, size + 1rem);
}
This means the hover width can be based on max-content and then adjusted by an additional amount.
| Feature | Use it when |
|---|---|
| interpolate-size | You want normal transitions to work between numeric sizes and intrinsic keywords |
| calc-size() | You need a calculation based on one intrinsic sizing keyword |
Animate Width to max-content
Intrinsic interpolation is not limited to height. Width can also transition from a fixed value to a content-based size.
Example:
:root {
interpolate-size: allow-keywords;
}
.tag {
width: 70px;
overflow: hidden;
white-space: nowrap;
transition: width 0.3s ease;
}
.tag:hover {
width: max-content;
}
When the browser supports the feature, the element grows smoothly from 70px to the width required by its content.
Use Progressive Enhancement
Older browsers that do not understand interpolate-size simply ignore the declaration. The layout can still work; it just may not animate between the intrinsic and numeric sizes.
You can also use @supports when a design depends on a particular sizing behavior.
.panel {
height: auto;
}
@supports (interpolate-size: allow-keywords) {
:root {
interpolate-size: allow-keywords;
}
.panel {
transition: height 0.3s ease;
}
}
Important Limitations
Intrinsic interpolation is not a promise that every sizing keyword can animate with every other keyword. The specification defines supported combinations and preserves layout semantics where intrinsic keywords behave differently.
For example, transitioning directly between two different intrinsic keywords can still be unsupported. The feature is mainly designed to bridge numeric sizes and intrinsic sizing values.
Common Mistakes
- Expecting all intrinsic keywords to interpolate with each other: support is defined for specific combinations.
- Forgetting overflow: a collapsing element may need overflow: clip or overflow: hidden so content does not remain visible while height approaches zero.
- Ignoring reduced-motion preferences: large size animations should respect users who prefer less motion.
- Using calc() instead of calc-size(): calc() cannot simply accept intrinsic sizing keywords in the same way.
Recommended Practices
- Use interpolate-size as progressive enhancement rather than making essential content depend on animation.
- Prefer a root-level opt-in when the behavior is appropriate across the entire interface.
- Use calc-size() only when you actually need calculations based on intrinsic size.
- Test expanding components with dynamic content because the intrinsic size can change.
Conclusion
interpolate-size makes previously awkward CSS transitions much simpler by allowing numeric sizes to animate to and from intrinsic sizing keywords such as auto. For most interfaces, setting interpolate-size: allow-keywords is the direct solution. Use calc-size() when you need additional calculations while preserving intrinsic sizing behavior.