フォロー

📝【団長のデバッグ道場🔥 vol.16】CSS の height がアニメーションしない!? auto の壁を突破せよ!

アコーディオンを作りたい。
transition: height .3s; を書いたのに、開閉が一瞬でパカッと切り替わる――
「CSS が効かない!?」と嘆く諸君、それは height:auto に潜む“仕様の壁”だ。


🧩 症状再現:高さ 0 → auto がパキッと切替

隠れていたテキストが表示されるはず…

<style>
  .panel {
    overflow: hidden;
    height: 0;
    transition: height .3s ease;
  }
  .panel.open {
    height: auto;
  }
</style>

<div>
<button id="btn">Toggle</button>
<div class="panel" id="panel">
  <p>隠れていたテキストが表示されるはず…</p>
</div>
</div>

<script>
btn.onclick = () => panel.classList.toggle('open');
</script>

開け閉めしてみると一切アニメーションせず、一瞬で全開・全閉。
なぜ transition が無視されるのか!?



🔍 真犯人:auto は数値に補間できない

CSS Transition は 数値0%→100%で補間して描画する仕組み。
しかし height:auto は計算後に決まる“実測値”であり、
ブラウザは 0px → 何px? を事前に把握できない。結果、補間不能 → 一括描画になる。


🛠️ 解決策:3 つの王道アプローチ

  1. max-height ハック
    実際に入り得る最大値を指定し、0 → 500px など数値遷移に置き換える。 .panel { max-height: 0; transition: max-height .3s ease; } .panel.open { max-height: 500px; /* 十分大きい値 */ }
  2. CSS animation + JS で動的数値
    開くときに scrollHeight を取得 & inline-style で高さを入れる → 閉じたら 0。
    例: panel.style.height = panel.scrollHeight + 'px'
  3. height ではなく transform
    スケールY や clip-path を使い、GPU フレンドリ&auto 問題回避。 .panel { transform: scaleY(0); transform-origin: top; transition: transform .3s ease; } .panel.open { transform: scaleY(1); }

📝 実装例:CSS だけで滑らかアコーディオン

ここに表示したいコンテンツが入ります。

<style>
  .panel {
    overflow: hidden;
    max-height: 0;               /* 閉じた状態 */
    transition: max-height .3s ease;
  }
  .panel.open {
    max-height: 500px;          /* 十分余裕を持たせる */
  }
</style>

<button id="btn">Toggle</button>
<div class="panel" id="panel">
  <p>ここに表示したいコンテンツが入ります。</p>
</div>

<script>
const btn   = document.getElementById('btn');
const panel = document.getElementById('panel');
btn.onclick = () => panel.classList.toggle('open');
</script>

最大高さ 500px を超える可能性がある場合は JS で scrollHeight を代入する方法に切り替えましょう。


📖 早見チェックリスト

  • transition するプロパティは「数値補間可能」か?
  • 0 → auto で詰まったら max-height or transform スケールを検討
  • JS 併用の場合は scrollHeight / offsetHeight を活用

🔧 ベストプラクティス:UI に応じた戦略を選ぶ

手法メリットデメリット
max-height ハックCSS だけで完結最大値を超えると欠ける
JS + height正確な高さで開閉JS 依存&コード量増
transform スケールGPU 高速・滑らか内部要素のアンチエイリアス揺れ

🧠 まとめ

  • height:auto は補間不可 → transition は効かない。
  • max-height / JS / transform で“数値遷移”に変換。
  • UI仕様・パフォーマンス要件で手法を選択せよ。

🔥 団長のエール

「効かない」と怒る前に、ルールを知ろう!
CSS が嫌がるのは曖昧な指示。
数値で示せばブラウザも全力で応えてくれる
設計の精度こそ、フロントエンドの武器だ。
戦え、そして滑らかに動け! お前の UI のように!!🔥

コメントする