JavaScript不要!CSSとGridで実現するスムーズな高さアニメーション

  • このエントリーをはてなブックマークに追加

CSSだけで高さ0から要素の高さまでの変化をtransitionでアニメーションさせたい

近年、CSSは色々な事ができるようになりました。
たとえばアニメーションの実装。
変化前後の値を利用する事で、アニメーションを実装する事ができます。

例えばこのように
a{color: #000; transition: 1s}
a:hover{color: #f00;}
とすると、a要素にマウスを乗せた時に黒(#000)から赤(#f00)へと変わります。
ここに“transition”をつけ足す事で、変化の途中の値を補完し続けてくれるので、アニメーションのように表示されます。
これは、widthやbadkground-color、borderでも同じように機能してくれます。
ですが、うまく機能しないケースもあります。

それは、height:0;からheight:auto;を動かしたい時です。
要素がどのくらいのサイズになるのか、autoでは上手く取得できないので機能してくれないんですね。
autoをやめて、height:0;からheight:200px;と明確な値を持せれば、機能してくれます。

それなら!と、200pxとか500pxとか、コンテンツが持つ実際の高さを持たせたとしましょう。
きちんと収まっている間は正常に表示されますが、中に入るコンテンツ量や文章量が変わったり、ブラウザやOSなどの環境が変わって、コンテンツの高さが変わると、レイアウトがおかしな事になります。

それではどうするのか…と考えた時に、jQueryやJavaScriptを使って、要素の高さを取得して使うという方法があります。
これはこれでアリなのですが、値を取得するまでの間、動作がワンテンポ遅れる事があります。

Gridを使って再現する

できることならCSSだけで機能を実装して、軽量なWebサイトを目指したいです。
ですが先ほどの内容を踏まえると、実現は難しそう…

いいえそんなことはありません!
CSSだけで、高さの変化をアニメーションさせる方法があるんです。
実は“Grid”を使う事で解決できます。

grid-template-rowsを活用する

autoでは実際の高さが取得できないのであれば、他の方法で値を入れればいいんです。
それを解決するのに、Gridが非常に役に立ちます!!

Gridには行の高さを制御する“grid-template-rows”があります。
これにはpxや%(パーセント)といった固定された単位の他に、“fr”(fraction)が用意されています。
frとは、他の行と比率で分けることができる単位です。

これによって、grid-template-rows: 0fr;からgrid-template-rows: 1fr;を指定して、変化させる事ができるようになります。
autoなどの曖昧な指定じゃなくなりましたので、実現できそうな雰囲気が出てきたんじゃないですか?

各ブラウザの対応状況について

実装する前に、各ブラウザの対応状況を確認していきましょう。
作業後に他のブラウザでは実装できない!という事がわかるととても悲しいので、事前の調査は大事ですよ。

メジャーなブラウザでは問題なく動作しているので、実装しても大きな問題にはならなそうですね。

実装の手段はこちら

実装してみよう!という事でサンプルソースと、実際に動いているサンプルを掲載しますね。

HTML
<div class=”block_trigger”>
<p>マウスを乗せると開くよ</p>
<div class=”block”>
<div class=”block_inner”>
ここにコンテンツが掲載されるよ
</div>
</div>
</div>

CSS
.block {
display: grid;
grid-template-rows: 0fr;
transition: .4s;
}
.block_trigger:hover .block {
grid-template-rows: 1fr;
}
.block_inner {
overflow: hidden;
}

上のソースを実際に動かしてみたものがこちら

マウスを乗せると開くよ

ここにコンテンツが掲載されるよ

開く動作が綺麗にアニメーションしていますね!
コレですよコレ!コレがやりたかったんですよ!

heghtを使った例はこちらです

マウスを乗せると開くよ

ここにコンテンツが掲載されるよ

こちらはカクカクしていますね。
開く・閉じるの動作としては正解ですが、理想とはかけ離れています。

子要素にoverflow: hidden;を設定する事がポイントです

0frを設定しても、overflow: hidden;を設定してあげなければ隠れてくれません。
また、余白を設けたい場合は、さらに子要素を用意して、そこにpaddingなどで余白を設けてください。

なんだか上手くいかない時には確認してみてくださいね。

まとめ

CSSを使って色々なアニメーションを実装する事ができますが、heightなどの高さが変わってしまう要素に対してアニメーションで表現する事は大きな課題でした。
それをGridを使って解決できるという情報を知った時には目から鱗というか、青天の霹靂というか、エッ?できるの?本当に?と、物凄く衝撃的でした。

これまでは要素の高さをjQuery等で取得して、トリガーとなる要素を操作した時に値を入れて…と処理をしていました。
CSSだけでできると知ってから実際に受け持っている案件で試したところ、とても簡単!そしてシンプル!まさにコレがやりたかった!

こういった実装作業はあまり多く利用する機会がなかったので、前回どうやったかな?jQueryどうやって書いたかな?と、立ち止まってしまう事もしばしばありました。
ですが、この方法を採れるのは本当に便利です。

クリックで開くコンテンツにも活用できます

今回はhoverでご紹介しましたが、JavaScriptを使ってクリックしたらclassを付与させてコンテンツを開く。というような時にも活用できます。

スマートフォンでの閲覧がメインになってきている現代において、押したら開くようなコンテンツが使いたい時に、どうしても開く動きをスムーズにしたいなぁ…と思う事が多くなっています。
その他にも、ページのナビゲーションにマウスを乗せた時に開くメニューに実装したりと、利用するシーンは多いはずです!
ぜひ役立ててみてください。
  • このエントリーをはてなブックマークに追加

CONTACTお問い合わせ

ホームページ制作に関するご質問などございましたら、
お気軽にお問い合わせください。

※ブログ記事に関するご質問はお答えしかねます。

TEL:0258-31-5005FAX:0258-37-7301

ホームページ制作やSEOのお悩みはぜひ弊社へご相談ください