height: auto のアニメーションを諦めなくていい。interpolate-size と calc-size() の使い方

はじめに

アコーディオンを開くときや、ホバー時にラベルをふわっと広げたいとき、height: autowidth: max-content に滑らかにアニメーションしたくなる場面はかなり多いです。これまではJavaScriptで高さを測ったり、max-height を大きめに決めてごまかしたりすることがよくありました。

最近は、その「本当はCSSだけでやりたかった」をかなり素直に書けるようになってきています。interpolate-sizecalc-size() を使うと、これまで急に切り替わっていた intrinsic size への変化を、対応ブラウザでは自然に補間できます。この記事では、まず基本の書き方を押さえつつ、実務で効きやすいアコーディオンやラベル拡張UIにどう落とし込むかをまとめます。

機能やライブラリの概要

interpolate-size は、automax-content のような intrinsic size keyword と、通常の長さの値を補間してよいかを切り替えるCSSプロパティです。初期値は numeric-only で、この状態では従来どおり height: auto などへは滑らかにアニメーションしません。allow-keywords を指定すると、対応ブラウザでサイズ変化を補間できるようになります。

一方の calc-size() は、intrinsic size をベースに計算したいときの関数です。たとえば「中身ぴったりの幅より、さらに 1rem だけ広くする」といった調整ができます。Chrome for Developers でも、基本的には interpolate-size を素直な第一候補にして、計算が必要なときに calc-size() を使う流れが勧められています。

地味ですが、この2つがあると次のような実装がかなり楽になります。

  • 開閉UIで height: auto を扱いたい
  • ナビゲーションやタグUIで width: max-content に気持ちよく伸ばしたい
  • JavaScriptで scrollHeight を測るほどではない、小さなサイズ演出をCSSに寄せたい

2026年3月31日時点では、MDNではどちらも Limited availability と案内されています。なので、「全面依存」ではなく「効く環境では自然に良くなる」という progressive enhancement として入れるのが実務では扱いやすいです。

基本の使い方

最初は、いちばんイメージしやすいアコーディオンからです。このコードでは、閉じたときは見出しぶんの高さにして、開いたら内容に合わせて auto まで広げます。

HTML
<details class="faq-item">
  <summary>配送日はどのくらいで確定しますか?</summary>
  <div class="faq-item__content">
    <p>
      注文内容の確認後、通常1営業日以内に確定します。繁忙期は少し遅れる場合があります。
    </p>
  </div>
</details>
CSS
@supports (interpolate-size: allow-keywords) {
  :root {
    interpolate-size: allow-keywords;
  }

  .faq-item {
    height: 3.25rem;
    overflow: clip;
    transition: height 0.35s ease;
  }

  .faq-item[open] {
    height: auto;
  }
}

このコードでやっていることはシンプルで、height の終点に auto を使えるようにしているだけです。以前よくあった max-height: 999px のような書き方に比べると、要素の実サイズに沿って素直に開くので、内容量が増減しても調整が崩れにくくなります。

なお、interpolate-size は継承するので、ページ全体で使いたいなら :root に置くのが分かりやすいです。逆に影響範囲を絞りたいなら、管理画面のメイン領域や特定コンポーネントの親要素だけに指定するほうが安全です。

便利な使いどころ

実務で特に使いやすいのは、「開閉」「展開」「ラベルの伸縮」の3つです。どれもJavaScriptで書けなくはありませんが、状態に応じてサイズが変わるだけなら、CSSで閉じたほうが保守しやすい場面が多いです。

1つ目はFAQや絞り込みパネルのような開閉UIです。CMS案件やLPの運用画面では、文量が後から変わることが多いので、固定値の max-height 方式だとメンテナンス時にズレやすくなります。height: auto に寄せられるだけで、この手の事故がかなり減ります。

2つ目は、アイコン付きナビやタグ候補の展開です。通常時はアイコンだけ見せて、ホバーやフォーカス時にラベルを自然幅まで広げると、情報量を増やしつつ見た目をコンパクトに保てます。このとき width: max-content へ補間できるのが効きます。

3つ目は、通知トーストや選択中チップのような「中身次第でサイズが変わる小さなUI」です。テキストの長短に応じた微調整をJavaScriptでやるほどでもないけれど、切り替えが急だと少し雑に見える。そういうところで、この機能はちょうどよく効きます。

応用コード

次は、calc-size() を使って「中身ぴったりより少し余白を持たせて広がる」ラベルボタンにしてみます。ここでは通常時を固定幅、ホバー時を max-content + 1rem として扱っています。

HTML
<nav class="tool-nav">
  <a href="#">
    <span aria-hidden="true"></span>
    <span class="tool-nav__label">保存済み</span>
  </a>
  <a href="#">
    <span aria-hidden="true"></span>
    <span class="tool-nav__label">設定</span>
  </a>
</nav>
CSS
.tool-nav {
  display: flex;
  gap: 0.75rem;
}

.tool-nav a {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  width: 3rem;
  padding: 0.75rem 1rem;
  overflow: clip;
  white-space: nowrap;
  border-radius: 999px;
  background: #1f2937;
  color: #fff;
  text-decoration: none;
  transition: width 0.28s ease, background-color 0.28s ease;
}

@supports (width: calc-size(max-content, size + 1rem)) {
  .tool-nav a:hover,
  .tool-nav a:focus-visible {
    width: calc-size(max-content, size + 1rem);
    background: #111827;
  }
}

このコードでは、ラベルの自然幅そのものではなく、「自然幅に少しだけ余裕を足したサイズ」に広げています。interpolate-size だけではできない「少し広めにしたい」が書けるので、チップUIやメニューの余白設計までCSS内で完結しやすくなります。

実案件だと、ここに prefers-reduced-motion も合わせておくと扱いやすいです。サイズ変化そのものは残しつつ、アニメーション時間だけ短くするくらいでも十分です。

CSS
@media (prefers-reduced-motion: reduce) {
  .faq-item,
  .tool-nav a {
    transition-duration: 0.01ms;
  }
}

動きの情報量を減らしたい環境では、無理に演出を見せないほうが親切です。特にアコーディオンやナビゲーションのように頻繁に触るUIは、この一手間の効果が分かりやすく出ます。

注意点

いちばん大事なのは、2026年3月31日時点で広くどこでも使える機能ではない、という前提で設計することです。MDNでも Limited availability 扱いなので、必ず @supports を使って「未対応でも破綻しない形」にしておくのが安全です。

もう1つ気を付けたいのは、interpolate-size では intrinsic size keyword 同士の補間はできないことです。たとえば min-content から max-content のような遷移は想定どおりに扱えません。基本的には「長さ or パーセント値」と「keyword」の間をつなぐ機能だと覚えておくと混乱しにくいです。

また、アコーディオンのように高さをアニメーションする場合は、途中の内容がはみ出さないよう overflow: clipoverflow: hidden を忘れないほうが見た目が安定します。CSSだけで済むようになっても、レイアウトの基本的な整え方は従来どおり重要です。

まとめ

interpolate-sizecalc-size() の良さは、派手な新機能というより、「今まで小さく面倒だったサイズ演出を、CSSだけで自然に書きやすくしてくれる」ところにあります。特に height: auto を扱いたい開閉UIや、max-content まで伸ばしたいナビゲーションでは、実装量も保守コストも素直に下げやすいです。

一方で、対応状況はまだ見極めが必要です。なので、まずは @supports で囲んだうえで、FAQ、絞り込み、トースト、ラベル付きボタンのような局所的なUIから試すのがおすすめです。対応環境では気持ちよくなり、未対応環境でも普通に使える。このバランスで入れると、実務でもかなり扱いやすい機能だと思います。

ポイント

  • height: autowidth: max-content の補間は、interpolate-size: allow-keywords でかなり素直に書ける
  • ページ全体へ一括適用するなら :root、慎重に試すならコンポーネント単位でスコープを絞る
  • 計算付きのサイズ変化が必要なときは calc-size() が便利
  • 2026年3月31日時点では Limited availability のため、@supports 前提の progressive enhancement が安全
  • 頻繁に触るUIでは prefers-reduced-motion も合わせて入れておくと実務向き

参考リンク

read next