5 min read

Unlocking Dynamic Layouts and Smooth Animations in CSS:Introducing calc-size and interpolate-size

Table of Contents

Introduction

The CSS properties calc-size and interpolate-size are new experimental features designed to address dynamic layout adjustments and animations more effectively. Let’s explore their roles and potential use cases.


Even non-fixed sizes can be animated.

The purpose of the calc-size() function and interpolate-size property is the same: they enable transition animations for dimension-related properties, such as width and height, even when the value is auto.

The most common example is the transition animation for height: auto.

<button onClick="this.classList.toggle('active');">click me</button>
<p>
    <img src="https://raw.githubusercontent.com/trevortylerlee/n1/main/n1.jpeg" width="256" />
</p>
p {
    height: 0;
    transition: height .25s;
    overflow: hidden;
}
.active + p {
    height: auto;
    height: calc-size(auto, size);
}

At this point, in Chrome version 129 and above, when you click the button, you will see the image displayed as a slice animation, as shown in the GIF below:

blog


Usage of interpolate-sizes

In fact, there’s an even simpler way to make height: auto support transition animations: by applying the CSS property to the ancestor container:

interpolate-size: allow-keywords;

ā€œInterpolateā€ refers to insertion or modification, and when used together, it represents the keyword that allows size interpolation changes.

For example, we can take a bolder approach and set it directly on the root element:

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

Therefore, on the page, all elements can trigger the height:auto transition animation effect without needing a special calc-size() configuration.

In other words, the calc-size() function is used to set individual elements, while interpolate-size allows for global settings across all elements.

When an element is set with a calc-size() value, the browser will automatically calculate its interpolate-size property value as ā€œallow-keywords,ā€ enabling size interpolation.

syntax

interpolate-size: allow-keywords;
interpolate-size: numeric-only;

The value ā€œnumeric-onlyā€ is the default interpolation rule, meaning that only numeric values will be interpolated.

Here’s an example illustrating this, using width as an illustration. The corresponding HTML and CSS code is as follows:

<button onClick="this.classList.toggle('active');">click me</button>
<figure>
    <img src="https://raw.githubusercontent.com/trevortylerlee/n1/main/n1.jpeg" width="256" />
</figure>
figure {
    width: 320px;
    padding: 1em;
    transition: width .25s;
    interpolate-size: allow-keywords;
    background: deepskyblue;
}
.active + figure {
    width: fit-content;
}

The effect is shown in the following GIF:

blog2


calc-size

The capabilities supported by the calc-size() function are quite rich, as shown in the example below:

/* Single-value setting */
calc-size(auto, size)
calc-size(fit-content, size)

/* Perform calculation */
calc-size(min-content, size + 100px)
calc-size(max-content, size - 80em)
calc-size(fit-content, size / 2)

/* Function-based calculation */
calc-size(auto, round(up, size, 50px))

The ā€˜size’ keyword represents the calculated size corresponding to the first keyword value in the function. If it’s an image, it refers to the image’s original size.

For example, if you want to click on a thumbnail image and have it zoom in to half of its original size with an animation, you can achieve this entirely with CSS—there’s no need for JavaScript. Here’s an example:

<img 
  src="https://raw.githubusercontent.com/trevortylerlee/n1/main/n1.jpeg" 
  onClick="this.classList.toggle('active');" 
/>
img {
    transition: .3s;
    width: 128px;
}
img.active {
    width: calc-size(fit-content, size / 2);
}

blog3


Not all CSS properties are applicable.

It is important to note that both the calc-size() function and the interpolate-size property are only applicable to certain CSS properties related to dimensions, such as width, height, padding, and sometimes margin.

For example, if you have a block-level element with margin: 0 by default, and you set margin: auto to center it, this won’t work with animation using calc-size() or interpolate-size. This is because margin: auto doesn’t directly involve the element’s dimension properties in the same way as other properties like width or height.

.element {
    margin: calc-size(auto, size);
}

blog4

The console displays an error message, as shown in the screenshot below. This occurs because margin: auto does not directly affect an element’s size-related properties like width or height, and therefore is not compatible with the calc-size() function or the interpolate-size property.


Revisiting the Animation of display: none

Previously, there were two main challenges with transition animations: one was height: auto, and the other was display: none.

In fact, display: none has a dedicated new feature to address this issue: the CSS transition-behavior property and the @starting-style rule.

If you’re interested, you can read this article: Using CSS transitions and animations, you can create animation effects even with display: none.


Compatibility across different browsers

The calc-size() function and interpolate-size property have been supported since Chrome version 129:

blog5