Web制作者の念願がついに叶った! height: 0;からheight: auto;へのトランジションをJavaScriptは無し、CSSで実装する方法
Post on:2023年12月7日
今までJavaScriptを使用しないと実装できなったことが、CSSだけで実装できるようになったものが増えてきました。たとえば、表示・非表示をdisplayプロパティでアニメーションできるようになったり、スクロールをトリガーにしたアニメーションなど、新機能が登場しました。
今回紹介するのは、height: 0;
からheight: auto;
へのトランジションです。高さが固定値であれば簡単にアニメーションできますが、コンテンツ量が不明で成り行きの場合はJavaScriptで高さを取得する必要がありました。
height: 0;
からheight: auto;
へのトランジションをCSSで実装する方法を紹介します。元記事を読んで、CSS Gridをここで使用するのか! と驚きました。
🧙♂️ CSS trick: transition from height 0 to auto!
by Francesco Vetere
下記は各ポイントを意訳したものです。
※当ブログでの翻訳記事は、元サイト様にライセンスを得て翻訳しています。
はじめに
長年CSSに携わってきた人なら、一度はheight: 0;
からheight: auto;
へのトランジションを試したことがあるかもしれません。そこで分かったことは、それが機能しない😢 ということでしょう。
しかし、ここに朗報があります!
今日、この問題を解決する実装方法があります。CSS Gridを使用することで、非常に簡単に、そして完璧に機能します!
さっそくその実装方法を解説します。
まずは、その元となるシンプルなアコーディオンをご覧ください。
See the Pen
Transition from height 0 to auto in pure CSS (1 / 4) by Francesco Vetere (@francescovetere)
on CodePen.
HTMLは、非常にシンプルです。
1 2 3 4 5 6 7 8 |
<div class="accordion"> <div class="accordion-title">Hover me!</div> <div class="accordion-body"> <div> <p>Lorem ipsum ...</p> </div> </div> </div> |
アコーディオンの上にマウスを置いてホバーすると、ドロップダウンが表示されます。これはこれで素晴らしいことですが、もしドロップダウンをスムーズなトランジションで表示したい場合はどうすればよいと思いますか?
CSSには、height
プロパティがトランジションするようにしてみました。
1 2 3 4 5 6 7 8 |
.accordion-body { height: 0; transition: 500ms height ease; } .accordion:hover .accordion-body { height: auto; } |
❌ 残念ながらこのCSSは機能しません。
トランジションせずに、アコーディオンが開閉するだけです。前述したように、height: 0;
からheight: auto;
へのトランジションはCSSでは不可能です。
🤔 これを解決するにはどうすればよいか
最初の解決策は、height
プロパティをauto
ではなく、固定値にすることです。
しかしこれは機能するかもしれませんが、素晴らしい解決策ではありません。アコーディオンの高さを数値で表すためにはJavaScriptで計算する必要があります、、、これは私が目指すものではありません!
😕 CSSのみで実装できますか?
💡 CSSのみで実装するには、どうすればよいでしょうか。auto
の代わりに、max-height
を使用すれば実装できるでしょうか?
1 2 3 4 5 6 7 8 |
.accordion-body { max-height: 0; transition: 500ms max-height ease; } .accordion:hover .accordion-body { max-height: 200px; } |
実際の動作は、下記をご覧ください。
See the Pen
Transition from height 0 to auto in pure CSS (2/4) by Francesco Vetere (@francescovetere)
on CodePen.
max-height
に固定値を定義しているため、ブラウザはトランジションを正しく実行できるようになりました。
😕 唯一の問題は、max-height
に固定値を定義しているため、コンテンツがオーバーフローする可能性があることです。たとえば、下記のようにアコーディオンのコンテンツ量が多い場合に対応できません。
See the Pen
Transition from height 0 to auto in pure CSS (3/4) by Francesco Vetere (@francescovetere)
on CodePen.
コンテンツ量が常に一定の高さを超えないのであれば、この方法を使用しても問題はありません。max-height
に適切な値を使用するだけで大丈夫です。
ただし、max-height
の値を大きくすればするほど、トランジションが奇妙になることに注意してください。たとえば、さきほどのデモでmax-height: 1000px;
にするとどのように変わるか試してみてください。
🤔 CSSで実装する最適解
CSSのみでもっとうまく実装できるでしょうか?
そもそも固定のheight
やmax-height
を避けることはできるのでしょうか?
それを解決するには、CSS Gridが役立ちます🎉
✅ 1つのグリッドアイテムでCSS Gridを作成するというテクニックで実装できます。
あとは、grid-template-rows
をofr
から1fr
にトランジションさせるだけです。これにより、グリッドアイテムが0
から「ナチュラルな」高さにトランジションします。とてもシンプルです!
1 2 3 4 5 6 7 8 9 10 11 12 13 |
.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; } |
CSSは、非常にすっきりしています。固定された高さや特殊なものもなく、アコーディオンが期待通りに動作します。
テキストを増やして試してください。まったく問題ありません、素晴らしい!😄
See the Pen
Transition from height 0 to auto in pure CSS (4/4) by Francesco Vetere (@francescovetere)
on CodePen.
CSS Gridを使用したこのテクニックの注意点が一つあります。これを機能させるためには.accordion-body
内のdiv
にoverflow: hidden;
を設定する必要があることです。私の個人的な意見ですが、このちょっとしたCSSの追加には十分な価値があると思います。
🎁 ボーナスチップス
このテクニックのポイントは、grid-template-rows
のアニメーション化が可能であるため機能します。この機能をサポートするブラウザは、下記の通りです。
grid-template-rowsのアニメーション化のサポートブラウザ
この記事を執筆している時点で、すべての主要なブラウザにサポートされていますが、実稼働コードでこの機能を使用する場合は、必ず最初に互換性を確認して使用してください。
以上です! CSSのこの素晴らしい機能をすでにご存じでしたら、お気軽にコメントをしてください😉
sponsors