【CSS】アニメーションをCSSで実現する方法(1)

ウェブデザインでは、ユーザーの目を引き、ページを魅力的に見せるためのさまざまなテクニックがあります。

画像アニメーションは、視覚的にインパクトを与える効果的な方法の一つです。

この記事では、CSSを使った画像アニメーションの例をいくつか紹介し、実際にコードを見ていきます。

(追記)第2回として本回で作成したCSSアニメーションの起動タイミング等を紹介したブログを執筆しましたのでそちらも御覧ください。

フェードイン

徐々にフェードインするアニメーションは非常にポピュラーで、視覚的に心地よい効果を与えます。

特にJavaScriptと組み合わせて、ページ読み込み時やスクロール時に使用されます。

今回はボタンで制御していますが、スクロールで発火させる方法は「第2回 スクロールで発動させる方法」として別途詳しく解説していますのでそちらをご確認下さい。

コード

HTML
<img class="expamle" src="image.jpg">
CSS
/* 初期状態:透明 */
.expamle {
  opacity: 0;
  transition: opacity 1.5s;
}

/* .showクラスが付与されたら:表示 */
.expamle.show {
  opacity: 1;
}
JavaScript
<button onclick="document.getElementById('example').classList.add('show')">
      フェードイン
</button>
<button onclick="document.getElementById('example').classList.remove('show')">
      リセット
</button>
Example Image

opacity(要素の透明度)

徐々にフェードインする効果をCSSで実現できます。これはopacity(オパシティ)を使ってアニメーションを作ります。

opacityは、CSSで使用されるプロパティで、要素の透明度を設定します。

値は0から1の範囲で指定され、0が完全に透明(見えない状態)、1が完全に不透明(見える状態)を意味します。

  • opacity: 1; → 完全に不透明(見える状態)
  • opacity: 0.5; → 50%の透明度(半透明)
  • opacity: 0; → 完全に透明(見えない)

ボタンを押すとshowクラスを追加

「表示」のボタンを押すと、JavaScriptで exampleクラスに show クラスを付与しています。

showクラスが付与されると、opacity: 1 が適用となり完全に見える状態(0->1)になります。

「リセット」のボタンを押すと、 show クラスを外して、同じ動作で見えない状態((0->1)に戻ります。

以降のJavaScriptのコードは全てこの様になっています。

transitionによる状態変化

この状態変化(0->1)の時に、CSSで定義されている transition が働き、opacityの値が「0」から「1」へ1.5秒かけて変化します。

transition: opacity 1.5s;

このtransitionがない場合は一瞬で変化します。

下記は、transitionがない場合のデモです。

Example Image

transitionについては「transitionについて」で、よりくわしく解説しています。

ズームイン

画像が拡大しながら表示されるズームイン効果はtransformを使って、画像を拡大するアニメーションを作成します。

このアニメーションでは、少しずつ拡大し、最終的に元のサイズになります。

コード

HTML
<img class="expamle" src="image.jpg">
CSS
.example {
  transform: scale(0);
  transition: transform 1.2s;
}

.example.show {
  transform: scale(1);
}

transformとは

transformは、CSSのプロパティで、要素の形状、位置、回転、スケーリング(拡大・縮小)などを変更するために使います。transformは、要素の視覚的な変化を行い、レイアウトに影響を与えないため、アニメーションやエフェクトに非常に便利です。

主なtransformの値

  • scale(): 要素のサイズを拡大・縮小します。
    • scale(1) → 元のサイズ(変更なし)
    • scale(1.5) → 1.5倍に拡大
    • scale(0.5) → 半分に縮小
  • rotate(): 要素を回転させます。角度を指定します。
    • rotate(45deg) → 45度回転
    • rotate(90deg) → 90度回転
  • translate(): 要素を指定した方向に移動させます。
    • translateX(50px) → 水平方向に50ピクセル移動
    • translateY(100px) → 垂直方向に100ピクセル移動
  • skew(): 要素を斜めに歪ませます。
    • skewX(20deg) → 水平方向に20度歪ませる
    • skewY(30deg) → 垂直方向に30度歪ませる
  • matrix(): 2D変形を行うための複雑な方法ですが、通常は他のプロパティ(scale, rotate, translateなど)を使う方が直感的です。

豊富なオリジナルブロックでLPをかんたんに作成できるLP Creator

LPをかんたんに作成できるLP Creator

デザイン・機能・SEO・収益化にこだわったメディア運営者向け「STREETIST」

デザイン・機能・速度・SEO・収益化にこだわった、ブロガー・メディア運営者向けのデザインテーマ STREETIST

スライドイン

画像がページ内にスライドインするアニメーションも、CSSだけで実現できます。opacitytransformを使用して、画像を指定した方向からスライドインさせます。

コード

HTML
<img class="example" src="image.jpg">
CSS
.example {
  opacity: 0;
  transform: translateX(100%);
  transition: transform 1.2s, opacity 1.2s;
}

.example.show {
  opacity: 1;
  transform: translateX(0);
}

3D回転アニメーション

画像に3D回転を加えることで、動きのあるインパクトを与えることができます。CSSのtransformを使って、画像を回転させるアニメーションを作成します。

コード

HTML
<img class="example" src="image.jpg">
CSS
.example {
  transform: rotateY(90deg);
  transition: transform 1.2s;
}

.example.show {
  transform: rotateY(0);
}

ドロップシャドウとぼかし効果

画像にぼかしやシャドウを追加して、ビジュアル効果を強調することも可能です。filterを使って、画像に効果を加えることができます。

このコードでは、画像がホバーされたときにぼかし効果がかかり、少し拡大するアニメーションを実現しています。

コード

HTML
<img src="image.jpg" alt="Slide In Image">
CSS
img {
  filter: blur(0);
  transition: filter 0.3s ease, transform 0.3s ease;
}

img:hover {
  filter: blur(5px);
  transform: scale(1.05);
}
Example Image

filter

filterはCSSで画像や要素に様々な効果を簡単に適用できるプロパティです。

以下のように複数のオプションを組み合わせることも可能です。

img {
  filter: brightness(1.1) blur(2px) grayscale(0.5);
}

代表的な効果は下記となります。
ボタンや画像のhover演出によく使われます。

フィルター名使い方例効果説明
blurfilter: blur(4px);ぼかし(ピクセル数を指定)
brightnessfilter: brightness(1.4);明るさ(1より大きい=明るい、1未満=暗い)
contrastfilter: contrast(150%);コントラストの強調(100%が元の状態)
grayscalefilter: grayscale(0.7);白黒(1で完全に白黒、0で通常カラー)
sepiafilter: sepia(1);セピア色(1でフルセピア、0で通常カラー)
hue-rotatefilter: hue-rotate(90deg);色相を回転(色合いを変える)
invertfilter: invert(1);色を反転(1で完全反転、0でそのまま)
opacityfilter: opacity(0.6);透明度(1が不透明、0が完全に透明)
saturatefilter: saturate(2);彩度(2で2倍に強調、1が元の色、0で白黒)
drop-shadowfilter: drop-shadow(2px 4px 6px #000);影を付ける

transitionについて

色々なアニメーションのサンプルを紹介してきました。

transitionは、CSSのプロパティが変化したときに、その変化をなめらかにアニメーションさせるためのプロパティです。

基本の書き方について

.sample {
  transition: [プロパティ名] [変化時間] [イージング] [遅延];
}

例えば下記は、要素が変化したら、opacity(透明度)をすぐに0.5sかけてease(なめらかな)変化させています。

.sample {
  transition: opacity 0.5s ease 0s;  
}

transitionのショートハンドではなく、細かく書く場合は下記の個別プロパティも使えます。

  • transition-property … 変化させるプロパティ名
  • transition-duration … 変化にかける時間
  • transition-timing-function … イージング(進み方)
  • transition-delay … 遅延開始(オプション)

設定値とデフォルトは次のようになっています。

設定項目デフォルト値意味
プロパティ名allすべてのプロパティが変化対象
変化時間(duration)0sアニメーションしない(即時変化)
イージング(timing-function)ease始めと終わりがなめらか
ディレイ(遅延、delay)0s遅延なし(すぐ開始)

デフォルト値があるので、上記の例は下記のように書くこともできます。

.transition-sample {
  transition: opacity 0.5s;  
}

また、複数の要素をアニメーション対象にすることも可能です。

複数の要素の変化等の設定値をそれぞれ変えることでさまざまなアニメーションを作ることができます。

.transition-sample {
  transition: opacity 0.5s, backgroud 0.5s, height 0.5s;  
}

transitionがない場合と、ある場合、allの場合

transitionがある場合と、ない場合に、どのような違いになるでしょうか?

また、transition: all 0.5s;allとは何でしょうか?

以下は、「ボタン」にカーソルが乗ると、背景色と横幅を変化させています。

※ 画面を広くしてご確認下さい。

A.transitionなし
背景色も横幅も
一瞬で切り替わる
B.横幅のみ指定
背景色は一瞬で
横幅だけ滑らかに変化
C.allを指定
背景色も横幅も
両方ゆっくり切り替わる

transitionがない場合は一瞬で切り替わり、transitionを指定しているプロパティだけはtransitionの定義に従って変化しています。

allをしていするとすべての要素が対象となります。

html
<div>A. transitionなし</div>
<button class="button btn1">ボタン</button>

<div>B. 横幅のみ指定</div>
<button class="button btn2">ボタン</button>

<div>C. allを指定</div>
<button class="button btn3">ボタン</button>
CSS(余計な箇所は除いています)
.button {
  width: 140px;
  background: #2196f3;
}
/* カーソルが乗った時の状態 */
.button:hover {
  width 100px; /* 横幅を狭める */
  background: #ec407a; /* 色を変える */
}

.btn1 {  }                      /* A. transition: なし */
.btn2 { transition: width 2s; } /* B. widthのみ */
.btn3 { transition: all 2s; }   /* C. 全て(widthとbackground) */
/* .btn3は、transition: 2s; と書くこともできます */

イージング(timing-function)について

アニメーションのスピードを調整します。

アニメーションの動きをコントロールすることができます。

例えば、ease-in を使用すると、アニメーションがスムーズに始まり、加速しながら進行するので、自然で心地よい動きが得られます。

animation-timing-function: ease-in;

一方、linear を使うと、均等に進行するアニメーションが必要な場合に適しています。

  • ease: アニメーションの始まりと終わりがゆっくり、途中は速くなります。(デフォルト)
  • ease-in: アニメーションの終了時に動きが遅く、途中から速く進みます。途中は速く動き、最後に遅くなります。
  • ease-out: アニメーションが終わるときに遅く、徐々に速くなります。
  • ease-in-out: アニメーションの最初と最後が遅く、途中が速い動きになります。スムーズに始まり、途中は速く進み、最後はまた遅くなります。
  • linier: アニメーションの動きが一定の速さで進行します。加速も減速もなく、均等に進行します。

※ 画面を広くしてご確認下さい。

ease
自然な動き(デフォルト)。最初と最後がゆっくり
ease-in
最初は遅く、だんだん速く動く
ease-out
最初は速く、最後はゆっくり止まる
ease-in-out
最初と最後が遅く、中間が速い
linear
常に同じ速さで動きます

応用編

このeaselinear などのイージング(動きの曲線)はあらかじめ用意されたものですが、cubic-bezier() を使うと、「どこで速く/遅くなるか」をさらに自由に細かく調整できます。

下記のように記述します。

cubic-bezier(X1, Y1, X2, Y2)

X軸(時間の進行)、Y軸(変化の進み方)で、0〜1の範囲で4つの数字を設定し、これら4点を通る曲線で、アニメーションの進み方が決まります。

例えば ease の場合は、cubic-bezier(0.25, 0.1, 0.25, 1.0) となります。

今回はcubic-bezierについて深堀りしませんが、下記のサイトで色々な変化を試すことができますのでご確認下さい。

赤色はあなたが設定した動きで、下の緑はLibraryから選んだもの(easeやlinearなどになっています)

https://cubic-bezier.com

簡単に解説しておきます。

上記のサイトを見てもらうとわかりますが、このような2次元グラフがあります。

横軸(X軸)は、 時間の進み具合(0秒→1秒)
縦軸(Y軸)は、 アニメーションの進捗(0→1)

左下のスタート(0,0)から、右上のゴール(1,1)がゴールとなっています。

例えば、cubic-bezier(0,0,1,1) は、時間の進み具合(X軸)と変化の進み具合(Y軸)が完全に一致 しているため、「加速も減速もせず」「常に一定速度」で変化します。

これは、linearと同じ動きになることがわかります。

遅延(delay)について

アニメーションを開始するまでの待ち時間を指定します。

下記はスタートボタンを押すと0.15秒ごとに順番にボールが浮かぶ(上に移動する)ものになります。

HTML
<div class=loader">
  <div class="dot"></div>
  <div class="dot"></div>
  <div class="dot"></div>
  <div class="dot"></div>
</div>
CSS
.dot {
  transition: transform 0.15s;
  transform: translateY(0);
}
.dot.lift {
  transform: translateY(-40px);
  background: #ec407a;
}
.dot:nth-child(1) {
  transition-delay: 0s;
}
.dot:nth-child(2) {
  transition-delay: 0.25s;
}
.dot:nth-child(3) {
  transition-delay: 0.5s;
}
.dot:nth-child(4) {
  transition-delay: 0.75s;
}

Transitionのまとめサンプル事例

これらの設定値を組み合わせて、各プロパティの変化の開始タイミングやイージングを細かくするとこういったアニメーションができます。

下記は下から徐々に拡大しながら2秒で表示させ、その後に3秒でぼかしが入り、更に2秒で消えていく、サンプルです。

html
<div class="box">
  <div class="wrap">
    <img src="image.jpg" alt="Slide In Image">
  </div>
</div>
css(余計な箇所は除いています)
img {
  /* 初期状態:下に200pxずらし、縮小しておく */
  transform: translateY(200px) scale(0);

 /*  それぞれのプロパティに個別設定 */
  transition:
    transform 2s ease-out 0s,
    filter 3s ease-in 2s,
    opacity 2s linear 5s;
}
/* アニメーションの設定 */
img.show {
  transform: translateY(0) scale(1);
  filter: blur(6px);
  opacity: 0;
}

いかがでしょうか?

transitionで様々なアニメーションが確認できたと思います。

続いては animation@keyframesを解説します。

徐々に背景色を変化させる

下記は6秒間で背景色の色を変化させているアニメーションです。

css
div {
  animation: example 6s infinite; /* 6秒間で繰り返しアニメーション */
}

@keyframes example {
  0% {
    background-color: red; /* アニメーションの最初の状態 */
  }
  50% {
    background-color: blue; /* アニメーションの途中の状態 */
  }
  100% {
    background-color: yellow; /* アニメーションの最後の状態 */
  }
}

@keyframesanimation

これまでは、transitionを利用して状態変化のアニメーションサンプルを解説してきました。

CSSのアニメーションは、transitionと別で、@keyframes ・animationを利用する方法があります。

transitionは状態変化時に1度だけ実行される単純なアニメーションに対し、@keyframesanimationは基本的にページが表示されると自動で実行され、アニメーションが繰り返し実行されます。(オプションで変更可能です)

@keyframes

@keyframesは、CSSでアニメーションを定義するためのルールです。

アニメーションの開始点(0%)から終了点(100%)までの状態を指定します。@keyframesを使うことで、アニメーション中に要素がどのように変化するかを段階的に設定できます。

@keyframes <定義名> で使用します。

下記は、アニメーションの開始(0%)で見えない状態(opacity: 0) から、終了(100%)時は見える状態(opacity: 1)に徐々に変化させるルールを定義(fadeInというルール名)を指定しています。

@keyframes fadeIn {
  0% { opacity: 0; }
  100% { opacity: 1; }
}

サンプルであった背景色の変化のように、0%・50%・100%のように途中の変化も設定可能です。

ここがtransitionと大きく異なる点です。

これを利用することで以下のようなアニメーションが作成できます。

animationについて

次に、animationについて詳しく解説します。

@keyframesで「どのように動かすか(例:transformopacityなどの変化)」定義したルールをanimationプロパティでどのタイミングで、何秒かけて、どんな繰り返し方で適用するかを細かく指定できます。

1つの@keyframesを複数の要素で使い回しすることができます。

基本の書き方について

下記は、@keyframesで定義した(fadeIn)を、2秒間でアニメーションさせ、終了後もその状態を保持する、設定例です。

この例では、imgに2秒かけて透明→表示(fadeIn)アニメーションが実行されます。

img { 
  animation: fadeIn 2s forwards; 
}
@keyframes fadeIn {
  0% { opacity: 0; }
  100% { opacity: 1; }
}

上記の設定例をデフォルトなしで、全て書くと以下のようになります。

animation: fadeIn 2s ease 0s 1 normal forwards running;

これは、下記のプロパティを同時に指定しています。

順番プロパティデフォルト値説明
1animation-namenoneアニメーションの名前(@keyframes名)
2animation-duration0s実行時間
3animation-timing-functionease進み方(イージング)
4animation-delay0s開始までの待ち時間
5animation-iteration-count1繰り返す回数
6animation-directionnormal再生方向
7animation-fill-modenone前後の状態の保持
8animation-play-staterunning再生・一時停止状態

animationプロパティのショートハンドではなく、各プロパティごとに指定することもできます。

img {
    animation: fadeIn 2s ease 0s 1 normal forwards running;
}

以下のように指定して書くことも可能で、後から書いたほうで上書きされます。

img {
    animation: fadeIn 2s ease 0s 1 normal forwards running;

    animation-name: fadeIn;
    animation-duration: 2s;
    animation-timing-function: ease;
    animation-delay: 0s;
    animation-iteration-count: 1;
    animation-direction: normal;
    animation-fill-mode: forwards;
    animation-play-state: running;
}

ここからはanimationのプロパティで指定できるオプションについて解説します。

animation-name アニメーションの名前(@keyframes名)

アニメーションの名前(@keyframes名)を指定します。

animation-duration 実行時間

アニメーションの実行時間(どれだけの時間で変化するか)を指定します。

animation-duration: 2s;   /* 2秒かけて実行 */
animation-timing-function 進み方(イージング)

アニメーションのスピードを調整します。

animation-timing-function: ease-in;

イージングについては「イージング(timing-function)について」で詳しく記載していますのでご確認下さい。

animation-delay 開始までの待ち時間

アニメーションを開始するまでの待ち時間を指定します。

複数の要素を順番にアニメーションさせたいときに利用します。

delayについては「遅延(delay)について」で詳しく記載していますのでご確認下さい。

// 各リスト項目が「少しずつ時間差で」アニメーションを開始できます。
li:nth-child(1) { animation-delay: 0s; }
li:nth-child(2) { animation-delay: 0.2s; }
li:nth-child(3) { animation-delay: 0.4s; }
animation-iteration-count 繰り返す回数

アニメーションを繰り返す回数を指定します。

/* 無限に繰り返す */
element {
  animation: example 3s infinite;
}

/* 3回繰り返す */
element {
  animation: example 3s 3;
}
animation-direction 方向

animation-direction: アニメーションが進む方向を制御します

animation-direction: reverse; /* 逆方向(100%→0%)で再生 */ 
  • normal: アニメーションが通常の順番(0% → 100%)で進行します。
  • reverse: アニメーションが逆方向(100% → 0%)で進行します。
  • alternate: アニメーションが順方向と逆方向を交互に繰り返します。例えば、最初は0%から100%まで進み、次に100%から0%に戻ります。
  • alternate-reverse: アニメーションが逆方向から始まり、順方向と逆方向を交互に繰り返します。

animation-fill-mode 開始前後のスタイル

アニメーション開始前や終了後に、どの状態(スタイル)を適用しておくかを指定できるプロパティです。

設定スタート前(delay)アニメ中終了後
なし(デフォルト)元のスタイル値keyframes元のスタイル値
forwards元のスタイル値keyframes最後のアニメ状態
backwards最初のアニメ状態keyframes元のスタイル値
both最初のアニメ状態keyframes最後のアニメ状態

少し分かりにくいと思いますが、かんたんに書くと以下のようになります。

none
→ アニメーション開始前も終了後も、元のスタイルに戻る(デフォルト)

forwards
→ アニメーション終了後、@keyframesの最後の状態のままになる。

backwards
→ アニメーション開始前(delay 遅延中)は、@keyframesの最初の状態を先に反映する。

both
→ 開始前は最初の状態、終了後は最後の状態を保持(forwardsbackwardsの両方)

以下のDEMOは4つのオプションの違いを表したデモです。ご確認下さい。

animation-play-state 状態管理

アニメーションの再生・一時停止状態を切り替えます。

animation-play-state: paused;    /* アニメーションを一時停止 */
animation-play-state: running;   /* 再生(デフォルト) */

animationとtransitionの違い

transitionは状態変化時に1度だけ、0%から100%の変化しか制御できないのに対し、@keyframesでは0%や10%、50%、100%と多段階で変化をつけることができ、かつ、animationで自動再生や繰り返し、状態管理などのオプションで制御ができます。

つまり、transitionは「ユーザーの操作や状態変化」に対してシンプルな動きを付けたい時に使い、animationは「自動的に動くアニメーション」や「複雑な連続動作」を作りたい時に使います。

transitionanimation(@keyframes)
発動タイミングプロパティの状態が変わった時のみ自動再生、繰り返し(オプションで変更可能)
制御の細かさシンプル(変化プロパティと時間だけ)複雑な動き・ループ・多段階変化が可能
利用方法定義したclass名を付与することで使い回し@keyframesで定義して使い回しが可能
代表的な使い方ボタンの色や影の変化、拡大縮小ページのローディング、スライドショー、バナー、連続アニメ

transitionやanimationの注意点

最後に、このtransitionanimation(@keyframes)についての注意点を解説します。

display: none からの表示・非表示はアニメーションできません

display: noneからdisplay: block時のアニメーションはできません。

一瞬で切り替わります。その他、

position(static, relative, absolute等)floatz-index などもアニメーションできません。

主に数値として連続的に変化できるもの(例:width, height, color, opacity, transform, background-colorなど)がアニメーション可能です。

@starting-style と transition-behavior を組み合わせればdisplayなども対象にすることができますが、まだ全てのブラウザで安定して使えるとは限りません。

auto値へのアニメーションは基本できない

例えば「height: 0 → height: auto」や「width: auto」など、ブラウザはアニメーションを計算できませんのでアニメーションができません。

アニメーションしたい場合は数値(remやpx、%など)で指定しましょう。

まとめ

いかがでしょうか?

@keyframesanimationtransition を駆使し、transformopacityなど様々なプロパティを動的に変化させることで、ページを魅力的にし、ユーザーの注目を集めることができます。

これらのアニメーションを活用することで、軽量でスムーズなユーザー体験を提供できます。

アニメーションの発動タイミングを制御したい場合は、JavaScript(例:Intersection Observerやイベントリスナー)と組み合わせます。

次回は、これらのアニメーションの発火タイミングの制御方法について詳しく解説しています。

ご確認いただければ幸いです。