[CSS] height:autoの時のtransitionをセットできるようにする方法

2023年10月25日

CSS Javascript

eyecatch cssのtransitionは、webページのちょっとした動きをセットするのに非常に便利に使えます。 ページ内の要素をボタンで表示したり、隠したりする場合や、プルダウンのメニューリストを表示する時に、ふわっとアイテムなどが現れるような効果や、サイズが大きくなっていくようなアニメーションにすることで、動きのあるwebページになって、ユーザーに興味を持ち続けてもらいやすくなります。 今回はそうした便利なtransition設定で、うまくサイズアニメーションができないケースで困った経験がある人も多いと思いますが、先日仕事で同じくできない事象にブチ当たったので、その解消方法をブログに残しておきます。

transitionを簡単に説明

このブログを読んでいるCSSコーダーの人の中で、もしかしたらtransitionについて知らない人もいるかもしれないので、簡単に使い方を解説しておきます。 ボタンを押すと、画像が表示される場合、transitionの設定をしていない場合と、している場合を比較してみましょう。

transitionを使用しない場合

この表示のソースコード <input type='checkbox' id='sample_1'> <label class='button_1' for='sample_1'>このボタンを押すと画像が表示されます。</label> <img src="sample.jpg"/>< <style> .button_1{ display:inline-block; background-color:#eee; cursor:pointer; border:1px solid #ccc; color:black; padding:5px 10px; border-radius:5px; font-size:0.8em; } input[type='checkbox']{ display:none; } .sample-1{ display:none; width:400px; height:200px; object-fit:cover; object-position: top; } #sample_1:checked ~ .sample-1{ display:block; } </style>

transitionを使用した場合

上記コードに追加したスタイルシート .sample-2{ height:0; transition-property:height; transition-duration:0.3s; } #sample_2:checked ~ .sample-2{ height:200px; }

解説

transitionは、要素のスタイルシートの値が変更する時に、その差分を指定した秒数で保管してアニメーションとして表示してくれる機能です。 要素のサイズだけじゃなく、位置や、色、透明度などもアニメーション化できるので、少しの変更で簡素なホームページから動きのあるホームページに様変わりさせることができます。 transition-propertyは、アニメーションを適用するcssプロパティを指定します。 この設定はしなくてもいいのですが、メモリ使用量が爆上がりする可能性があるので、できれば、指定しておいたほうが賢明です。 transition-durationは、アニメーションの実行時間です。sは秒で、msはミリ秒で指定できます。 他にも、keyframeアニメーションと同じ様にタイミングやdelayなどの指定もできるので、リファレンスサイトを眺めてみると良いでしょう。 MDN: css transition

ブラウザの適用状況

現時点でほぼすべてのブラウザが対応しているので、デファクト・スタンダード機能と言ってもいいでしょう。

位置のtransition

<input type='checkbox' id='sample_3'> <label class='button' for='sample_3'>このボタンを押すとボールが移動します。</label> <div class='sample-3'></div><style> .sample-3{ display:block; width:100px; height:100px; border-radius:50%; background-color:#aeddcd; transform:translateX(0); transition-property:transform; transition-duration:0.3s; } #sample_3:checked ~ .sample-3{ transform:translateX(250px); } </style>

色のtransition

<input type='checkbox' id='sample_4'> <label class='button' for='sample_4'>このボタンを押すと箱の色が変わります。</label> <div class='sample-4'></div><style> .sample-4{ display:block; width:100px; height:100px; border-radius:5px; background-color:#aeddcd; transition-property:background; transition-duration:0.3s; } #sample_4:checked ~ .sample-4{ background-color:red; } </style>

透明度のtransition

<input type='checkbox' id='sample_5'> <label class='button' for='sample_5'>このボタンを押すと箱の透明度が変わります。</label> <div class='sample-5'></div><style> .sample-5{ display:block; width:100px; height:100px; border-radius:5px; opacity:1.0; background-color:#aeddcd; transition-property:opacity; transition-duration:0.3s; } #sample_5:checked ~ .sample-5{ opacity:0.1; } </style>

height:autoではtransitionが使えない

ヘッダメニューなどでこのtransitionを使って、メニューの出し入れを表現したくても、transitionは、"auto"という値に対してアニメーションをしてくれません。 もちろん、サイズをpxや%などで指定すれば適用できるのですが、autoで対応するためにいくつかの裏技も存在するようです。 でも、確実に行うためには、Javascriptで対応するしかないというのも仕方がないことのようなので、簡単にコピペで使えるようにスニペットを用意しておきました。

メニューにtransitionを適用

<input type='checkbox' id='sample_6'> <label class='menu' for='sample_6'>メニューリスト▼</label> <ul class='sample-6 menu-lists'> <li>リスト-1</li> <li>リスト-2</li> <li>リスト-3</li> <li>リスト-4</li> <li>リスト-5</li> </ul><style> .menu{ display:inline-block; background-color:#aeddcd; padding:5px 10px; margin-bottom:5px; cursor:pointer; } .menu-lists{ display:flex; flex-direction:column; gap:5px; overflow:hidden; padding:0!important; } .menu-lists.sample-6{ height:0; transition-property:height; transition-duration:0.3s; } .menu-lists > *{ background-color:#aeddcd; padding:5px 10px!important; list-style:none!important; text-align:center; margin:0; } #sample_6:checked ~ .sample-6{ height:auto; } </style> autoがサイズ指定できないので、transitionが効きません。

height:autoに適用させる裏技

.menu-lists.sample-7{ max-height:0; transition-property:max-height; transition-duration:0.3s; } #sample_7:checked ~ .sample-7{ max-height:300px; } メニューの内容によって、サイズが変動するため、heightに固定値を入れられない時は、max-heightに最大値をセットすることで、表示がheight:autoのままで対応できるという裏技です。 この方法のデメリットは、最大値を見極める必要があるという事です。 そして、あまりにも最大値を大きくした場合、閉じるタイミングにズレが生じてしまうため、ちょっとしたストレスが生まれる可能性があります。

簡単なJavascriptで対応

<input type='checkbox' id='sample_8'> <label class='menu' for='sample_8'>メニューリスト▼</label> <ul class='sample-8 menu-lists'> <li>リスト-1</li> <li>リスト-2</li> <li>リスト-3</li> <li>リスト-4</li> <li>リスト-5</li> </ul><style> .menu-lists.sample-8{ height:0; transition-property:height; transition-duration:0.3s; } </style><script type='module'> const list_area = document.querySelector('.sample-8') document.getElementById('sample_8').addEventListener('click',(e=>{ const height = list_area.scrollHeight const from = e.target.checked ? 0 : height const to = e.target.checked ? height : 0 list_area.animate([ {height:`${from}px`}, {height:`${to}px`} ],{ duration: 300, iterations : 1, fill : "forwards" }) })) </script> javascriptが難しいと思っている人には、少しハードルが高いかもしれませんが、そんなにたくさんのコードを書かなくてもheight:autoに対応するコードは書けることが分かります。 自身のメニューなどの箇所に合わせて書き換えてお使いください。

あとがき

transitionは、使っているwebページと使っていないwebページでは、クオリティが断然違ってくるので、ホームページ作りにおいてのプラスクオリティで必ず考えてみてはいかがでしょうか?

人気の投稿

このブログを検索

ごあいさつ

このWebサイトは、独自思考で我が道を行くユゲタの少し尖った思考のTechブログです。 毎日興味がどんどん切り替わるので、テーマはマルチになっています。 もしかしたらアイデアに困っている人の助けになるかもしれません。

ブログ アーカイブ