CSSだけでマウスオーバーでフェードイン・フェードアウトの概要
注意 ※バージョンや環境によっては正常に動作しない可能性があります。
CSSだけでフェードイン・フェードアウトする方法です。
display:noneを使うバージョンは以下になります。
トリガーはマウスオーバーで、CSSのhoverを使います。
display:noneを使わずに、heightの指定で要素を非表示にします。
CSSのtransitionだけで実装できるのが利点です。
ただ、jQueryで設定したほうが直感的な簡単、というのが自分の印象です。
あと、気になるのが、height 0 指定でアニメーションをすると、動きががくがくするんですよね。なんかちょっと気になるんですよね。なので自分では採用していない方法です。
動作サンプル
ここをマウスオーバー。
マウスオーバーで出てくる。animationでフェードイン。
自分が思っている動作ではないけど、display:noneを使用したときよりは高さの縮み方はアニメーションしている。でもがくがく感がある。
非表示をpaddingやheightを0にして対応しているため、transitionで出てくる時に、その要素も影響を受ける。
他に良い設定方法があるかも。
ソースコード
HTML
<div class="trigger"> <p>ここをマウスオーバー。</p> </div> <div class="result"> <p>マウスオーバーで出てくる。animationでフェードイン。</p> </div>
CSS
.trigger{ background-color: #8a0b00; color: #fff; padding:.5rem; } .result{ height: 0; padding: 0; overflow: hidden; transition :1s; opacity: 0; } .trigger:hover ~.result { background-color: #fff; border: 1px solid rgba(0, 0, 0, 0.125); border-radius: 0.25rem; padding: .5rem; margin: .5rem; transition :1s; height: auto; opacity: 1; }
ソースコードの説明
trigerクラスはをマウスオーバーすると、resultの見た目が変化するCSSです。
resultの初期値は、透明度、高さや余白を0にし、要素がはみ出したとしてもスクロールバーが表示されないoverflowの設定をしています。非表示になるときにもアニメーションさせたいので、transitionの設定もしています。
trigerの疑似クラスのhoverでは、同一階層の要素として「~」を指定し、resultクラスを設定しています。
CSSセレクタの書き方で、様々な要素を指定することができます。data属性を使えばかなり柔軟に対応できそうですが、それをやるなら最初からJavaScriptかjQueryを使うほうがよさそうな気がします。
子要素に対して動きを設定する方法などは、以下のページで少し触れています。
マウスオーバー時のresultは、見た目と余白、transitionの時間、高さ、透明度を表示する設定にしています。
heightとopacityの値が表示される形になるため、マウスオーバーされると1秒間でその値に変化していきます。
- 初期値でheight: 0にして要素を非表示にする
- heightを0してもpaddingは残るので0にする
- 要素がはみ出している、と判定されるとスクロールバーが表示されるので、overflowをhiddenにする
- hoverに同一階層の要素「~」を使って、表示されるresultを設定する
- transitionでアニメーションの時間を設定する
まとめ
CSSだけでアニメーションを設定する際には、display:noneを指定したクラスにアニメーションが利かないため、レイアウトを含めた非表示にしてフェードアウトさせようとすると、要素の高さを無くすという無理やりな方法になります。
今回は疑似クラスのhoverをトリガーにしていますが、inputタグとラベルを使って、チェックボックスを非表示にしてクリックをトリガーにすることもできます。
ですが、jQueryが使える環境ならば、fadetoggleを使うほうが楽で簡単です。
CSSだけでの実装は、どうしてもjQueryやJavaScriptが使えないけどフェードイン・フェードアウトをして要素を消したい、という時の方法です。
これは個人的な好みの問題ですが、あんまり使いたくないやり方です。
フェードイン・フェードアウトをせずに、display:noneで瞬時に切り替えか、アニメーションをしたいのならばjQueryかJavaScriptを使用する、ほうが良い気がします。
paddingの要素を全てゼロにしているので、paddingの反映にもtransitionが影響し、文字自体が斜めに動く形になっていますが、paddingの高さ要素だけ0にして、左右paddingは表示の時と同じにすると、文字も縦に出てくるアニメーションになります。
厳密には、borderもheight 0では消えないので、こだわる人はそういった要素も全て含めて、上手くいく方法を探してみると良いと思います。