ある要素にマウスホバーやクリックイベントを行い、非表示の要素を「display: none;」から「display: block;」に切り替える際、transitionを使用して要素を徐々に表示させようとすると、transitionが効かず要素が瞬時に出現してしまい困ったなという経験はないでしょうか。

今回の記事では、displaytransitionが効かない時の対処法について解説します。

displayにtransitonが効かない

今回はマウスホバーイベントで考えます。

HTML

<div class="content"></div>;

CSS

.content {
  display: none; //要素を非表示。
}
.content:hover {
  display: block; //要素を表示。
  transition: .3s; //アニメーションの速度を指定。
}

上記のようにdisplayを使用しnoneからblockに切り替えて非表示の要素を表示させる際、transitionは効かず要素が高速に出現します。
実はdisplayプロパティにtransitionを指定しても動作しません。

なぜdisplayにtransitonが効かないのか

transition「2つの要素を対象にその状態間の変化を定義する」プロパティです。
要素を非表示にする「display: none;」は存在が無効にされた状態であるため、transitionの対象にはならず、transitionを指定しても反応しないのです。

displayにtransitonが効かない時の対処法

transitionを使用して表示非表示の変化を指定したい時はdisplayを使用するのではなく、visibilityopacityの2つのプロパティを併用することで、transitionを機能させることができます。

CSS

.content {
  visibility: hidden;//文書のレイアウトを変更することなく要素を非表示。
  opacity: 0;
}
.content:hover {
  visibility: visible;//文書のレイアウトを変更することなく要素を表示。
  opacity: 1;
  transition: .3s;//アニメーションの速度を指定。
}

visibilityとopacityの併用が必要な理由

visibilityopacityの二つのプロパティが必要な理由について、片方のみ指定した場合を考えてみます。

visibilityのみ指定した場合

visibilityプロパティはdisplayと同様に要素の表示非表示を指定するプロパティですが、visibility: hidden;display: none;のように要素の存在を完全に無効にするわけではなく、レイアウト自体は変更されません。

見えないしクリックもできないが、そこにはあるというイメージです。

したがって要素自体は存在するので、transitionが適用されます。

しかし、visibilityを指定しただけではtransitionで要素を徐々に表示させることができません。displayを使用した時のように、要素が高速に表示されます。
visibilitytransitionの適用対象ではありますが、単独で使用すると変化をつけられません。

.content {
  visibility: hidden;//文書のレイアウトを変更することなく要素を非表示。
}
.content:hover {
  visibility: visible;//文書のレイアウトを変更することなく要素を表示。
  transition: .3s;//アニメーションの速度を指定。
}

opacityのみ指定した場合

opacityプロパティは要素の透明度を指定するプロパティです。二つの要素にopacity: 0;opacity: 1;を指定し、transitionを使用してイベントを発生させると要素が徐々に表示されます。

しかし、opacity: 0;で透明にした要素はdisplayのように完全に消えるわけではないので、要素をクリックできてしまい非常に厄介です。非表示コンテンツの下にリンクなどがある場合、そのリンクをクリックすることができなくなります。

.content {
  opacity: 0;
}
.content:hover {
  opacity: 1;
  transition: .3s;//アニメーションの速度を指定。
}

visibilityとopacityを併用した場合

visibilityopacityを併用した場合、片方のみ指定した場合の問題をすべて解決することができます。
opacityのおかげでtransitionの変化をつけることができ、visibilityのおかげで要素をクリックできなくなります。
お互いの短所を補っているわけです。

.content {
  visibility: hidden;//文書のレイアウトを変更することなく要素を非表示。
  opacity: 0;
}
.content:hover {
  visibility: visible;//文書のレイアウトを変更することなく要素を表示。
  opacity: 1;
  transition: .3s;//アニメーションの速度を指定。
}

まとめ

以上、displaytransitionが効かない時の対処法について解説しました。
表示非表示の際にアニメーションをつけたい時はvisibilityopacityを使用すると良いでしょう。

参考
transition – CSS: カスケーディングスタイルシート
visibility – CSS: カスケーディングスタイルシート