バナー

この教材は「ギャクサン」というWeb制作学習カリキュラムの一部です。

はじめての方はこちらからご覧ください👉

更新日

08|CSSのアニメーション|animationとtransition2つの使い分けをマスターしよう

web兄さん

:hoverの擬似classを使用してのアニメーションではtransitonを使いましたね。

transitionは直訳すると変遷、つまりプロパティの移り変わり方を指定するプロパティです。

transitionでアニメーション

a{
  background-color: #fff;
  color: #333;
  
  /* プロパティが遷移する時間を指定 */
  transition: color 0.5s, background-color 0.5s;
}

a:hover{
  background-color: #086ec9;
  color: #fff;
}

このようにプロパティ単位のシンプルな動き方をスムーズに遷移させることにtransitionは向いていますが、以下のような課題があります。

  1. アニメーションを起こすにはキッカケが必要(例:ホバーやクリックなど)
  2. 変化の状態が元に戻ってしまう(例:ホバーを解除したら元の状態に戻る)
  3. 無限ループのアニメーションは作成できない
  4. 複雑な変化には対応できない

これらを一挙に解決できるプロパティが、今回紹介するanimationプロパティです!

animationの書き方

色の変わるボタンをanimationを使って再現してみます。

ページを更新するとボタンの色が変化します

更新すると、一度青色のボタンに変化して、また「パッ!」と元に戻ったと思いますがこれは正常な動きです。戻り方を滑らかにする方法や、アニメーションの状態を保つ方法については後述します。

animationでアニメーション

今回のサンプルはanimationで必要な最低限のコードを書いてみました。

a{
  animation: change-color 2s;
  
  /* 上記は以下のショートハンド */
  animation-name: change-color; /* 設定するアニメーションの名前 */
  animation-duration: 2s;  /* アニメーションが完了するまでの時間(今回は2秒) */
}

@keyframes change-color{
  0% {
    background:#fff;
    color: #333;
  }
  50% {
    background:#FF6658;
    color: #fff;
  }
  100% {
    background:#086ec9;
    color: #fff;
  }
}

web兄さん
以下の動画の解説を見るとより理解がスムーズになるはずです!
animationプロパティの概要

アニメーションの回数をコントロールする

animation-iteration-count0%→100%までを1カウントとして、アニメーションさせる回数を制御することができます。例では3回アニメーションが繰り返されます。

※ページを更新するとアニメーションが開始されます。

img{
  animation: slide 1s 3;
}

@keyframes slide{
  0%{
    transform: translateX(0)
  }
  100%{
    transform: translateX(150px)
  }
}

値にinfinite(無限)を指定すればループアニメーションも可能です。

img{
  animation: 3s linear infinite loop-rotate;
}

@keyframes loop-rotate {
  0%{ transform:rotate(0);}
  100%{ transform:rotate(360deg);
}

アニメーションの実行を遅らせる

animation-delayを使用すればアニメーションが実行されるタイミングをズラすことができます。

例えば以下のようなケースに有効です。

※ページを更新するとアニメーションが開始されます。

<img src="photo.jpg">

<img class="two" src="photo.jpg">

<img class="three" src="photo.jpg">
img{
  animation: slideup 1s;
}

.two{
  animation-delay: 1s; /* 1秒後に実行 */
}
.three{
  animation-delay: 2s; /* 2秒後に実行 */
}

@keyframes slideup{
  0%{
    transform: translateY(0)
  }
  100%{
    transform: translateY(-50px)
  }
}

アニメーションにかける時間を設定する

animation-durationを使用することでアニメーションが完了するまでの時間を設定することができます。

:hoverで使用したtransitionでも同じようにtransition: color 0.3sのように時間を設定しましたよね。

delayがアニメーションを開始させるまでの時間設定だったのに対して、duration開始から終了までにかける時間を設定します。

※ページを更新するとアニメーションが開始されます。

<img src="photo.jpg">

<img class="two" src="photo.jpg">

<img class="three" src="photo.jpg">
img{
  animation: slideup 1s;
}

.two{
   /* 5秒かけて実行 */
  animation-duration: 5s;
}
.three{
  /* 10秒かけて実行 */
  animation-duration: 10s;
}

タイミングをズラすならdelayが一般的

delaydurationの違いを説明しました。どちらも要素ごとにアニメーションの時間をズラすことができますが、よくあるタイミングをずらして実行するアニメーションではanimation-delayを使用する場合がほとんどですので覚えておきましょう。

完了後の見た目を保持する

先ほどから紹介しているサンプルでは、アニメーションの完了後に「パッ」ともとの状態に戻ってそまいますよね。

animatin-fill-modeを使用することでアニメーションが終わった後の要素の見た目をどうするかを設定できます。

※ページを更新するとアニメーションが開始されます。

<img src="photo.jpg">

<img class="forwards" src="photo.jpg">
img{
  animation: radius-slide 4s;
}

.forwards{
  animation-fill-mode: forwards;
}

@keyframes radius-slide{
  50%{
     border-radius: 30px;
  }
  100%{
     transform:translateX(200px);
  }
}

animation-fill-mode: forwardsが設定されている画像は移動した後に移動箇所に残り続けていますよね。

100%時点で設定されているプロパティのみ適用される

サンプルのアニメーションを見ると途中で画像の角が丸くなり、アニメーションの完了時には角丸がなくなっています。これはanimationのプロパティは@keyframesで設定した%の中でだけ適用されるためです。

つまり、border-radius0%→50%にかけて適用されていき、50%→100%にかけて解除されていきます。

100%時点で角丸を適用していたい場合は100%の箇所にもborder-radiusを書けばOKです。

@keyframes radius-slide{
  50%{
     border-radius: 30px;
  }
  100%{
     border-radius: 30px;
     transform:translateX(200px);
  }
}

イージングを設定する

動画で解説をしています

animation-timing-functionについての解説

イージングとは動きの加減を表す言葉です。字面だけではわかりづらいと思うので以下の例を見てみてください。

このサンプルはdelaydurationも全く同じ設定です。

しかし、animation-timing-functionだけが以下のように異なることでアニメーションの加減に差が出ています。


linear(均一)

ease-in(ゆっくり始まり加速)

ease-out(速く始まり減速)

ease-in-out(加速して減速)

.one{ animation-timing-function: linear; }

.two{ animation-timing-function: ease-in; }

.three{ animation-timing-function: ease-out; }

.four{ animation-timing-function: ease-in-out; }

cubic-bezierを使えば細かな設定も可能

.bezier{
  animation-timing-function: cubic-bezier(0.52, 1.48, 0.4,-0.78)
}

cubic-bezier()関数を使用することでベジェ曲線に従ってイージングを設定することができます。

数値をひとつずつ指定するのは難しいので、デベロッパツールで動きを確認しながら設定するのが良いでしょう。

transitionについて

今回animationの解説をメインに行いましたが、transitionもほぼ同じプロパティが用意されています。

プロパティ役割
transition-propertyどのプロパティの遷移をコントロールするかの設定transition-property: color background-color
transition-duration変化の開始から終了までにかかる時間の設定transition-duration: 0.3s
transition-delay変化を開始するまでにかかる時間の設定transition-delay: 1s
transition-timing-function変化の加減を設定transition-timing-function: linear

※アニメーションの回数や完了後の見た目の保持はanimationにしかありません。

これらのプロパティは以下のように全てtransitionを使ってショートハンドで書くことも可能です。

p{
  transition: color 0.3s 1s linear;
}

animationとtransitonの違い

animationtransition
アニメーション完了後のスタイルの維持維持可能(animation-fill-mode: forwards適用前に戻る
アニメーションが解除される時パッと戻るスムーズに戻る
アニメーションの繰り返し回数の指定ができる1度しか実行できない
アニメーションの段階的な操作できるできない
向いているケース・ページが読み込まれた時のフェードインのアニメーション
・繰り返しのアニメーション
・ホバーやクリック時のみ起こすアニメーション

最大の違いはtransitionは厳密にはアニメーションではなく、「変化の仕方」を設定するプロパティです。そのため適用後の変化を維持することができません。

その性質を考えると「〇〇している時だけ」変化が起きて、それ以外は通常に戻るという条件において相性が良いプロパティと言えます。

どちらを使用するか迷ったら

記述量は、言うまでもなくtransitionの方がシンプルですよね。

そのため、基本的な考え方としては優先度を「transiton > animation」として、transitionで再現できない場面ではanimationを使用すると考えておきましょう。