マウスオーバーで別要素をanimationとkeyframesでフェードインする概要
注意 ※バージョンや環境によっては正常に動作しない可能性があります。
トリガーをマウスオーバーすると、要素がフェードインで表示され、離すと瞬時に非表示になるcssです。
cssだけで実装できるので、JavaScriptを使いたくない時でも利用できます。
今回紹介するコードには弱点がありまして、display:noneを使用しているため、フェードアウトのアニメーションができないことです。
cssの公式のリファレンスに書いてありますが、cssのanimation設定は、display:noneを読み込むと全て停止するようになっています。そのため、アニメーションが利かないのです。
この表示非表示の方法は、トリガー部分にちょっとマウスが乗ったり離れたりすると画面ががくがくしてしまうので、それが嫌でボツにした方法です。
とりあえず備忘録として記事にしておこうと思います。
- animationとkeyframesでフェードイン
- 非表示はdisplay:none
- hoverでdisplay要素を表示にする
動作用サンプル
注意 ※基本chromeでの動作確認だけなります。他のブラウザやモバイルでは正常に動作しない可能性があります。
表示・非表示要素が同一階層
ここをマウスオーバー。(trigger-div)
test用pタグ。trigger-divとresult-contentsの間に入っている。
マウスオーバーで出てくる。animationでフェードイン。(result-contents)
トリガーの要素と、表示される要素のタグが、同一階層にあれば、間に他のタグがあっても動作します。
疑似クラスhoverの後に、「~」をつけてクラスを指定します。
.trigger-div:hover ~.result-contents{}/*同一階層要素*/
表示・非表示要素が隣接
ここをマウスオーバー
マウスオーバーで出てくる。animationでフェードイン。トリガーと表示要素が隣接していると動作する。
トリガーと表示要素が隣接している場合です。
以下のように「+」をつけてクラスを指定します。
.trigger-div:hover +.result-contents{}/*隣接要素*/
表示・非表示要素が子要素
ここをマウスオーバー
マウスオーバーで出てくる。animationでフェードイン。トリガー内に表示要素がある場合に動作する
トリガー要素タグ内に入っている要素に対して動作します。
赤の背景色がトリガー要素で、その中に表示要素が入れ子になっています。
.trigger-div:hover .result-contents{}/*子要素*/
ソースコード
HTML
<div class="trigger-div"> <p>ここをマウスオーバー。</p> </div> <p>test用pタグ。トリガー要素と非表示要素の間に別のタグが入っていても動作する</p> <div class="result-contents"> <p>マウスオーバーで出てくる。animationでフェードイン。</p> </div>
CSS
.trigger-div{ background-color: #8a0b00; color: #fff; padding:.5rem; } .result-contents{ display:none; } .trigger-div:hover ~.result-contents{ display:block; animation: fadein 1s forwards; background-color: #fff; border: 1px solid rgba(0, 0, 0, 0.125); border-radius: 0.25rem; padding: .5rem; margin: .5rem; } @keyframes fadein { 0% { opacity: 0; } 100% { opacity: 1; } }
コードの説明
trigger-divの要素にマウスオーバーさせると、trigger-divに設定した疑似クラスhoverが動作して、cssが適用される形になっています。
マウスオーバーはtigger-divですが、実際に動作するのはresult-contentsクラスなります。
triger-divには見た目の設定がしてあります。
result-contentsには初期の表示設定としてdisplay:noneを設定してあります。これで、最初は非表示状態になります。
tigger-divの疑似クラスhoverを設定し、trigger-divをマウスオーバーした際の設定が記載されています。
:hoverの後にクラスを指定することで、trigger-divクラスをマウスオーバーすると、result-contentsクラスに設定が反映されるようになっています。
hoverをトリガーに別要素にcssを反映させる
hoverの後の書き方で、反映される要素が変わります。この辺りの細かい部分は、cssセレクタの書き方をググっていただければと思います。ここでは、三種類だけ例を上げておきます。
.trigger-div:hover ~.result-contents{}/*同一階層要素*/ .trigger-div:hover +.result-contents{}/*隣接要素*/ .trigger-div:hover .result-contents{}/*子要素*/
スペースを開けての書き方は、cssの書き方ではよくあるやつですね。子要素に反映されます。
「+」は隣接する要素です。hoverで別要素、となると使いどころはあるかな~といった感じです。
「~」要素が離れていても、同一階層にあれば反映される設定です。
あまり複雑なことをしなければ、この辺りを覚えておけばそんなに困らないかな~と思います。
上手くdivタグでの囲み方を調整できれば、表示場所をpositionで固定する、なんて使い方もできます。
jQueryやJavaScriptを使えば、そんなに頭をひねらなくても、かなり自由度の高い設定ができますが、CSSだけだと結構考えないといけないので大変です。
animationとkeyframesの設定
フェードインのアニメーションは、animationとkeyframesで設定しています。
@keyframes fadein{ 0% { opacity: 0; } 100% { opacity: 1; } }
keyframesの後に、任意の名前で変数のように(今回はfadein)設定して、{}で処理を書きます。
位置を%で指定し、その際のスタイルを設定します。今回は、0%の時に透明度を0、100%の時に透明度を1にしています。
animationではkeyframesで指定したfadeinを指定し、その開始から終了までの時間とその方向を指定しています。今回は1秒でforwardsとしています。forwardsは終了状態のスタイルに100%のものが適用される形です。
.trigger-div:hover ~.result-contents{ animation: fadein 1s forwards; }
今回は透明度しか設定していませんが、パーセントごとに位置を指定して要素を動かしたり、確度を指定して回転させたり、
animationやkeyframesでは様々な設定の方法があるので、リファレンスを確認すると、自身の要件にあっているものが見つかるかもです。
まとめ
cssだけで実装できるのでお手軽です。フェードアウトしなくて良いのならばかなり簡単です。
transitionでも同じようなことができそうですね。
複雑なことをするならばanimationですし、単純でよければtransitionで十分だったりします。その辺りは要件次第でしょうか。transitionのほうが対応ブラウザが多いので、業務で幅広いブラウザバージョンに対応しなければならない場合は、transitionのほうが安全かもですね。
完全に非表示にするアニメーションは、正直cssだけで設定すると、自分の思う通りの動作をしてくれなくて、結局JavaScriptやjQueryを使うことになり、自分はほとんど採用していません。
ですが、多少の動きの悪さは目をつぶっても、cssだけで実装できるというのは、利点としてあるのかな、とは思います。
ワードプレスでも動いてますし、テーマによるとは思いますが、需要はあるかもですね。
そういう時が自分も来るかもしれないので、それようの備忘録として記事にしています。