🧙‍♂️ CSSの小技:heightを0からautoへの移行について

もしあなたがCSSをしばらくいじり続けていれば、height: 0からauto遷移させようとした経験が、少なくとも一度はあるはずです...しかし、それが動かないことに気づくでしょう!😢

➡️ 幸いなことに、今ではこの問題に対する解決策があります。それはCSS Gridを活用しており、驚くほど簡単で、完璧に機能します

実用例から始めましょう。シンプルなアコーディオンを作りました:

HTMLはとてもシンプルです:

<div class="accordion">
  <div class="accordion-title">Hover me!</div>
  <div class="accordion-body">
    <div>
      <p>Lorem ipsum ...</p>
    </div>
  </div>
</div>

フルスクリーンモードにする フルスクリーンモードを解除する

アコーディオンにマウスでホバーすると、ドロップダウンが現れるのに気づくでしょう。それはクールですが、もし私たちがそれをもっと滑らかなスムーズな遷移で現れるようにしたいとしたらどうでしょう?

実際に、前述のcodepenでheightプロパティに少しの遷移を加えてそうしようと試みました

.accordion-body {
  height: 0;
  transition: 500ms height ease;
}

.accordion:hover .accordion-body {
  height: auto;
}

フルスクリーンモードにする フルスクリーンモードを解除する

❌ 残念ながら、これは機能しませんheight: 0からheight: autoへの遷移は、前にも言ったように、CSSでは不可能なことなんです。

🤔 どうすれば解決できるでしょうか?

まず一つめの解決策は、heightプロパティをautoの代わりに固定数値にすることです。

これは機能しますが、それほどいい方法ではありません:この固定数値を計算するためには、.accordion-bodyが実際にどれだけ高いかを計算するためにJavaScriptに頼る必要がある...これが本来の目的ではありません

😕 我々はまだこの効果を達成できますが、CSSオンリーの解決策とは?

💡 実は、はい! なぜmax-heightを使ってみないのでしょうか?

.accordion-body {
  max-height: 0;
  transition: 500ms max-height ease;
}

.accordion:hover .accordion-body {
  max-height: 200px;
}


フルスクリーンモードにする フルスクリーンモードを解除する

これが結果です:

max-heightについて固定値を定義したので、ブラウザは今、正しく遷移を実行できます。

😕 ただ一つの問題は、max-heightに固定値を定義しているので、コンテンツが溢れる可能性があるということです:

もし、あなたのコンテンツが常に一定の高さに達しないと確信していれば...これを使うのが完全にOKですmax-heightに適切な値を使いさえすれば問題ありません。

それでも、max-heightの値が高ければ高いほど、遷移が奇妙になることには注意してください(以前のcodepenでmax-height: 1000pxを試して、どう変化するか見てみてください!)。

🤔 もっと良くできるでしょうか?最初からheight/max-heightを固定しないようにできるでしょうか?

🎉 CSS Gridが救いになります!

✅ 実際に私たちが使える素晴らしい小技があります。それは、単一のグリッドアイテムを持つCSSグリッドを作成することです。

その後、私たちはgrid-template-rowsを取り、0frから1frへ遷移させるだけです:このようにして、私たちのグリッドアイテムはゼロからその"自然な"高さまで遷移します。それがとても簡単です:

.accordion-body {
  display: grid; 
  grid-template-rows: 0fr;
  transition: 250ms grid-template-rows ease;
}

.accordion:hover .accordion-body {
  grid-template-rows: 1fr;
}

.accordion-body > div {
  overflow: hidden;
}

フルスクリーンモードにする フルスクリーンモードを解除する

これはとてもクリーンに感じます。固定した高さや変わったことはなく、ただ期待通りに機能するアコーディオンだけです。素晴らしいです!😄

この解決策に対する唯一の注意点は、これを機能させるためにoverflow: hidden.accordion-bodyの内側のdivに設定する必要があることです。私の意見としては、この少しの追加CSSは完全に価値がありますが、コメントであなたがどう思うか教えてください!

🎁ボーナスヒント

このトリックが機能するのは、grid-template-rows(また、広義ではグリッドトラック)のアニメーション化が可能なためです。

これは、いくつかのブラウザにとっては結構最近の機能です:このページを訪問すると、例えばChromeではバージョン107から始まるグリッドトラックのアニメーション化が可能になったことがわかります。

この記事を書いている時点では、すべての主要なブラウザがこの機能をサポートしていますが、プロダクションコードでこの機能を使いたい場合は、まず互換性を確認してください!


以上です!この素晴らしいCSS機能について既に知っていたかコメントで教えてくださいね! 😉

次回まで!👋

Buy Me A Coffee

こちらの記事はdev.toの良い記事を日本人向けに翻訳しています。
https://dev.to/francescovetere/css-trick-transition-from-height-0-to-auto-21de