画像を徐々に表示する CSS アニメーション

画像が際立つCSSアニメーションのサンプル

Akira

福岡在住ウェブデザイナー。 WordPress のカスタマイズを、「見やすさ」と「使いやすさ」にこだわり紹介しています。

画像が際立つ CSS アニメーションのご紹介です。アイキャッチ画像や本文中の画像、ランディングページの画像など、いろいろな画像に使えます。

サンプルは、便宜上アニメーションの再生回数を無限にしています。(提示している CSS のアニメーション回数は 1 回です。)

共通の HTML 。

<div class="img-wrap">
    <img>
</div>

左から徐々に表示するアニメーション。

CSSアニメーションのサンプルに用いた画像

CSS 。

.img-wrap {
  overflow: hidden;
  position: relative;
}

.img-wrap:before {
  animation: img-wrap 2s cubic-bezier(.4, 0, .2, 1) forwards;
  background: #fff;
  bottom: 0;
  content: '';
  left: 0;
  pointer-events: none;
  position: absolute;
  right: 0;
  top: 0;
  z-index: 1;
}

@keyframes img-wrap {
  100% {
    transform: translateX(100%);
  }
}

上記 CSS の translateX(100%)translateX(-100%) と値をマイナスにすると、右から表示するアニメーションに。

CSSアニメーションのサンプルに用いた画像

CSS 。

.img-wrap {
  overflow: hidden;
  position: relative;
}

.img-wrap:before {
  animation: img-wrap 2s cubic-bezier(.4, 0, .2, 1) forwards;
  background: #fff;
  bottom: 0;
  content: '';
  left: 0;
  pointer-events: none;
  position: absolute;
  right: 0;
  top: 0;
  z-index: 1;
}

@keyframes img-wrap {
  100% {
    transform: translateX(-100%);
  }
}

今度は画像の中心から、円形に広がるアニメーション。( IE ・ Edge・ AMP では、アニメーションしません。)

CSSアニメーションのサンプルに用いた画像

CSS 。

.img-wrap {
  animation: img-wrap 2s cubic-bezier(.4, 0, .2, 1);
}

@keyframes img-wrap {
  0% {
    clip-path: circle(0 at 50% 50%);
    -webkit-clip-path: circle(0 at 50% 50%);
  }
  100% {
    clip-path: circle(100% at 50% 50%);
    -webkit-clip-path: circle(100% at 50% 50%);
  }
}

ただし、 IE と Edge は clip-path に未対応。また、 AMP は 、 @keyframesclip-path を使えません(ただし、使っても AMP エラーは出ない)。いずれでもアニメーションされず、ただ普通に画像が表示されます。

2 つの領域で異なるアニメーション

画像を 2 つの領域に分け、それぞれ異なるアニメーションにしてみます。 HTML は、これまでのものと変わりません。

<div class="img-wrap">
    <img>
</div>

画像の上部は左から、下部は右から表示するアニメーション。

CSSアニメーションのサンプルに用いた画像

CSS 。

.img-wrap {
  overflow: hidden;
  position: relative;
}

.img-wrap:before,
.img-wrap:after {
  animation: 2s cubic-bezier(.4, 0, .2, 1) forwards;
  background: #fff;
  content: '';
  left: 0;
  pointer-events: none;
  position: absolute;
  right: 0;
  z-index: 1;
}

.img-wrap:before {
  animation-name: img-wrap-before;
  top: 0;
  bottom: 50%;
}

.img-wrap:after {
  animation-name: img-wrap-after;
  top: 50%;
  bottom: 0;
}

@keyframes img-wrap-before {
  100% {
    transform: translateX(100%);
  }
}

@keyframes img-wrap-after {
  100% {
    transform: translateX(-100%);
  }
}

今度は画像の左側は上から、右側は下から表示するアニメーション。

CSSアニメーションのサンプルに用いた画像

CSS 。

.img-wrap {
  overflow: hidden;
  position: relative;
}

.img-wrap:before,
.img-wrap:after {
  animation: 2s cubic-bezier(.4, 0, .2, 1) forwards;
  background: #fff;
  bottom: 0;
  content: '';
  pointer-events: none;
  position: absolute;
  top: 0;
  z-index: 1;
}

.img-wrap:before {
  animation-name: img-wrap-before;
  left: 0;
  right: 50%;
}

.img-wrap:after {
  animation-name: img-wrap-after;
  left: 50%;
  right: 0;
}

@keyframes img-wrap-before {
  100% {
    transform: translateY(100%);
  }
}

@keyframes img-wrap-after {
  100% {
    transform: translateY(-100%);
  }
}

3 つ以上の領域で異なるアニメーション

<div> を使えば画像を 3 つ以上の領域に分け、それぞれ異なるアニメーションを指定できます。

CSSアニメーションのサンプルに用いた画像

HTML 。

<div class="img-wrap">
    <div class="cover1"></div>
    <div class="cover2"></div>
    <div class="cover3"></div>
    <img>
</div>

CSS 。

.img-wrap {
  overflow: hidden;
  position: relative;
}

.cover1,
.cover2,
.cover3 {
  animation: cover 2s cubic-bezier(.4, 0, .2, 1) forwards;
  background: #fff;
  height: 33.4%;
  left: 0;
  pointer-events: none;
  position: absolute;
  right: 0;
  z-index: 1;
}

.cover1 {
  top: 0;
}

.cover2 {
  animation-delay: .2s;
  top: 33.333333%;
}

.cover3 {
  animation-delay: .4s;
  top: 66.666666%;
}

@keyframes cover {
  100% {
    transform: translateX(100%);
  }
}

スクロールアニメーション

画像が画面内に入ると、アニメーションが始まります。画像が見えなくなるまでスクロールすると、再度アニメーションをご確認いただけます。(ただし、 AMP ではアニメーションしません。)

CSSアニメーションのサンプルに用いた画像

HTML 。

<div class="img-wrap">
    <img>
</div>

JavaScript 。

( function() {
    const image = document.querySelectorAll( '.img-wrap' );
    
    const observer = new IntersectionObserver( function( entries ) {
        entries.forEach( function( entry ) {
            if( entry.intersectionRatio > 0 ) {
                entry.target.classList.add( 'img-animation' );
            } else {
                entry.target.classList.remove( 'img-animation' );
            }
        });
    });
    
    Array.prototype.forEach.call( image, function( img ) {
        observer.observe( img );
    });
})();

CSS 。

.img-animation {
  animation: img-opacity 2s cubic-bezier(.4, 0, .2, 1);
  overflow: hidden;
  position: relative;
}

.img-animation:before {
  animation: img-animation 2s cubic-bezier(.4, 0, .2, 1) forwards;
  background: #fff;
  bottom: 0;
  content: '';
  left: 0;
  pointer-events: none;
  position: absolute;
  right: 0;
  top: 0;
  z-index: 1;
}

@keyframes img-opacity {
  0% {
    opacity: 0;
  }
}

@keyframes img-animation {
  100% {
    transform: translateX(100%);
  }
}