
こんにちは!静岡県浜松市でWEBデザイナーをしています小瀧です。
CSSでアコーディオンや詳細表示を作るとき、必ずと言っていいほど悩むのが height: auto の扱いです。
高さが固定なら transition は簡単。
でも中身の量が変わると、auto を使わざるを得ない。
結果、JavaScriptで高さを計算して style に入れる。
そんな実装を何度もしてきたと思います。
CSSだけで完結させたい。
そう思いながらも、長年それは不可能でした。
その常識を変えたのが calc-size() と interpolate-size です。
これらは、CSSが「サイズの変化」を理解できるようにするための新しい仕組みです。
この記事では、height: auto がなぜアニメーションできなかったのか。
そして、なぜ今できるようになったのかを、実務視点でカタログ形式にまとめます。
なぜ height:auto はアニメーションできなかったのか
CSSの transition は、数値同士の補間で動きます。
しかし auto は数値ではありません。
- 100px から 300px は補間できる
- auto は計算結果が確定しない
- そのため補間できない
これが、長年の制約でした。
従来の回避策
JavaScriptで scrollHeight を取得し、高さを直接指定する方法が主流でした。
calc-size()とは何か
calc-size() は、サイズを計算対象として扱うための新しい関数です。これにより、auto を含むサイズ指定が可能になります。
height: calc-size(auto);
これだけではアニメーションしません。
重要なのは、数値との間をつなぐ役割です。
interpolate-sizeの役割
interpolate-size は、サイズ補間のルールを指定します。interpolate-size: allow-keywords;
これを指定することで、auto などのキーワードも補間対象になります。
calc-size()とinterpolate-sizeは必ずセットで使います。
基本構文カタログ
開閉アニメーションの基本形
HTML
<button id="toggle">開閉</button>
<div class="panel">
<p>ここに可変コンテンツが入ります。</p>
<p>高さは auto です。</p>
</div>
CSS
.panel {
height: calc-size(0px);
overflow: hidden;
transition: height 0.4s ease;
interpolate-size: allow-keywords;
}
.panel.is-open {
height: calc-size(auto);
}
JavaScript
const btn = document.getElementById('toggle');
const panel = document.querySelector('.panel');
btn.addEventListener('click', () => {
panel.classList.toggle('is-open');
});
よくあるUI別カタログ
アコーディオン
HTML
<button class="accordion-btn">メニューを開く</button>
<div class="accordion-content">
<p>アコーディオンの中身です。</p>
<p>行数が増えてもOK。</p>
</div>
CSS
.accordion-content {
height: calc-size(0px);
overflow: hidden;
transition: height 0.3s ease;
interpolate-size: allow-keywords;
}
.accordion-content.is-open {
height: calc-size(auto);
}
JavaScript
const accBtn = document.querySelector('.accordion-btn');
const accContent = document.querySelector('.accordion-content');
accBtn.addEventListener('click', () => {
accContent.classList.toggle('is-open');
});
続きを読むボタン
HTML
<div class="more-text">
<p>最初に見せたいテキスト。</p>
<p>ここから先は続きを読む。</p>
<p>コンテンツ量は自由です。</p>
</div>
<button id="moreBtn">続きを読む</button>
CSS
.more-text {
height: calc-size(4em);
overflow: hidden;
transition: height 0.4s ease;
interpolate-size: allow-keywords;
}
.more-text.is-expanded {
height: calc-size(auto);
}
JavaScript
const moreBtn = document.getElementById('moreBtn');
const moreText = document.querySelector('.more-text');
moreBtn.addEventListener('click', () => {
moreText.classList.toggle('is-expanded');
moreBtn.textContent =
moreText.classList.contains('is-expanded')
? '閉じる'
: '続きを読む';
});
詳細パネル表示
<button id="detailBtn">詳細を見る</button>
HTML
<div class="detail-panel">
<p>詳細情報が表示されます。</p>
<p>説明文が増えても対応できます。</p>
</div>
CSS
.detail-panel {
height: calc-size(0px);
overflow: hidden;
transition: height 0.5s ease;
interpolate-size: allow-keywords;
}
.detail-panel.is-show {
height: calc-size(auto);
}
JavaScript
const detailBtn = document.getElementById('detailBtn');
const detailPanel = document.querySelector('.detail-panel');
detailBtn.addEventListener('click', () => {
detailPanel.classList.toggle('is-show');
});
max-heightトリックとの違い
- max-height は上限を決め打ちする必要がある
- 要素量が増えると壊れる
- calc-size(auto) は実サイズに追従
実務的なメリット
コンテンツ量を気にせずCSSだけで制御できる。
使えるプロパティと注意点
- height や width で使用可能
- overflow:hidden が必須な場合が多い
- ブラウザ対応は段階的
常用する場合はフォールバック設計が重要です。
フォールバック設計カタログ
@supports (height: calc-size(auto)) { .panel { transition: height 0.4s; interpolate-size: allow-keywords; } }
未対応環境では、従来手法に切り替えられます。
JavaScript削減という観点
- scrollHeight計算が不要
- resize監視が不要
- DOM操作が減る
CSSがレイアウトを理解する時代に入っています。
まとめ
calc-size() と interpolate-size は、長年CSS制作者を悩ませてきた height:auto 問題を根本から解決します。
JavaScriptに頼らず、CSSがサイズ変化を補間する。
これは単なる新機能ではなく、
CSS設計思想そのものの進化です。
今すぐ全面採用は難しくても、
知っているかどうかで設計の引き出しは大きく変わります。
次世代CSSの標準テクニックとして、ぜひ押さえておきましょう。












