[CSS] visibilityを使ったフェードインアニメーションを実装する方法

概要

jQueryのfadeIn()で使用されるようなフェードインアニメーションは、display: noneが要素に当たるため、領域の確保(高さ・横幅が担保)がされない。そのためアニメーション時にレイアウトのガタツキが起こる可能性がある。

display: noneを要素に当てると「無い状態」になってしまう為、あくまで「見えない状態」にしたい場合はvisibility: hiddenを当てるのが良い。さらに言うと、visibility: hiddenはクリックする事ができない。そしてクリックしたり、アニメーションさせたりするのであればopacity: 0が必要になる。

実装

下記のような実装をすることでフェードインアニメーションが可能となる。

#target {
  visibility: hidden;

  &.visible {
    visibility: visible;
    animation-duration: .5s;
    animation-name: fade-in;
  }
}
@keyframes fade-in {
  0% {
    visibility: hidden;
    opacity: 0;
  }

  50% {
    visibility: visible;
    opacity: .5;
  }

  100% {
    visibility: visible;
    opacity: 1;
  }
}

何らかの方法でvisibility: hiddenが当たっている#target.visibleクラスをセットすることでフェードインしながら表示が可能になる。
Intersection Observerを使った要素検出と併用しても良いかもしれない。

単純にopacityだけでアニメーションするのも可能だが、hover時に要素ないにマウスポインターが変わる要素があったりすると格好が悪いし、visibilityだけではアニメーションできないため併用している。