🪗

autoなheightでもアニメーションができるようになる!calc-size() について

2024/08/27に公開

Chrome129calc-size() 関数がデフォルトで使用可能になります。
可変のボックスに対するアニメーション付与がかなり楽になる予感がするのでご紹介します。

calc-size() ってなに?

固有サイズの設定キーワードが指す実際の数値を、計算に利用できる関数です。
固有サイズの設定キーワードの例として次のようなものがあります。

auto
min-content
max-content
fit-content
stretch
contain

使い方

calc-size(<basis>, <calculation>)
  • 第1引数:使用したい設定キーワード
  • 第2引数:計算式(basisで算出された数値がsizeという変数に代入されます)

width: calc-size(min-content, size * 1.5)

このように書くと、min-contentが 10px だった場合、算出結果は 15px になります。

嬉しいこと:アコーディオンの実装がCSSのみでできるようになる

これまではアコーディオンのような高さが可変なものに対してアニメーションをつける場合は、

  • jsを使う
  • gridを使ったハッキーな方法を使う

といった少々回りくどい方法で実装するしかありませんでした。

calc-size()を使えば、CSSのみでアニメーション付きのアコーディオンが実装できるようになります!

calc-size()のデモ

早速calc-size()を使ってアコーディオンを実装してみましょう。
checkboxがチェックされたときにアコーディオンが開くように、次のようなHTML/CSSで作りました。

<section class="accordion">
  <h2 class="summary">calc-size()を使って開閉するアコーディオン</h2>
  <input type="checkbox" class="size-calc">
  <div class="content">
    <p>アニメーションがつきます!!</p>
  </div>
</section>
.accordion {
  border: 1px solid black;
}

.content {
  height: 0;
  overflow: hidden;
  transition: height 500ms ease;
}

.size-calc:checked + .content {
  /* calc-size()未対応のブラウザのためのフォールバック */
  height: auto;

  height: calc-size(auto, size);
}

calc-size()を使って実装したアコーディオンの動き

このコードの重要な部分はCSSで指定しているアコーディオンが開かれた状態のheightプロパティです。

.size-calc:checked + .content {
  height: calc-size(auto, size);
}

第1引数に 固有サイズの設定キーワードであるautoを設定し、第2引数でsizeを指定しています。
このように書くことで、算出されたコンテンツの高さが height として指定されます。

注意点

使い所を間違えない
さて、便利なcalc-size()関数ですが、要素の固有サイズの変更(=ブラウザの画面サイズを変えた場合に変更された要素のサイズなど)には対応していません。

It is not a goal of this feature to support animation of a change in size that results from a change to the element's intrinsic size (for example, when the content changes and the element becomes taller or shorter as a result).

(出典:csswg-drafts

要素の固有サイズが変化した場合にトランジションが有効になるわけではないので、注意が必要です。

フォールバックを用意しておいた方が安全
まだ全てのブラウザで利用可能な関数ではないため、calc-size()だけの記述だとinvalidな値になってしまうケースがあります。対応策として、アコーディオンの高さ指定のような使い方の場合はautoを手前においておくと安心です。

.size-calc:checked + .content {
  height: auto;
  height: calc-size(auto, size);
}

interpolate-size プロパティについて

calc-size()とセットで発表されているプロパティについても少しご紹介します。
ページ全体に対して、固有サイズの設定キーワードを拾ってアニメーションさせるかを設定できる互換性のためのプロパティです。

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

このように設定することで、先ほどの例でheight: autoを用いていたアコーディオンもアニメーション付きで開閉されるようになります。

ブラウザの実装状況

感想

これまでアコーディオンといったら何らかのライブラリを使ったり、頑張ってjsで高さを取得してアニメーションをつけたりしていた一手間があったので、今回の関数の追加は嬉しいです!
既存のアコーディングに対し必要に応じてheight:autoを付与した上で、interpolate-sizeプロパティで一気にアニメーションを付与するといった対応もできそうです。

参考

株式会社ナレッジワーク

Discussion