CSS
animation
cssアニメーション

【面倒くさい人向け】@keyframesアニメーションのこれ覚

自分の中ではつい先日まで、Webサイトでアニメーションを実装するには、

・単一で簡単なアニメーションはCSS transition
・連続した複雑なアニメーションはJavaScript

だったんですが、
アニメーションの管理がCSSとJavaScriptの2つに別れているのが気持ち悪く思えてきたのと、
今更ながらCSSの@keyframesアニメーションの良さを理解できたんで、
これさえ覚えておけば@keyframesアニメーションが使えるようになりますよーというまとめ。

@keyframesはややこしい?むずかしい?

@keyframesアニメーションは直感的にわかりずらい!
そんなふうに考えていた時期が俺にもありました。

例えばこのコードとか

css
div {
  opacity: 0;
  width: 50px;
  height: 50px;
  background: #000;
  animation-name: anime01;
  animation-duration: 2s;
  animation-timing-function: ease;
  animation-delay: 0s;
  animation-iteration-count: 1;
  animation-direction: normal;
  animation-fill-mode: none;
  animation-play-state: running;
}

@keyframes anime01 {
  0% {
    opacity: 0;
    transform: translateY(50px);
  }
  25% {
    background: #000;
    transform: translateY(0);
  }
  50% {
    opacity: 1;
    background: #f00;
    transform: scale(1);
  }
  100% {
    opacity: 0;
    background: #f00;
    transform: scale(1.4);
  }
}

See the Pen gZMNqN by kiti-net (@kiti-net) on CodePen.

「えーと、アニメーションの継続時間が2秒で、それの25%は0.5秒でtranslateYが0になって…50%は1秒だから……ややこしい!」
「設定するプロパティー多っ!」
「@keyframe使えん!」

となってる気の短い人は、そもそもの@keyframesの触れ方が悪かったんだと思います。

そんな人でも基本的に下記の3つのポイントさえ抑えておけば、
@keyframesを簡単に扱えるようなります。

1.アニメーションを小さく分解する

上記のアニメーションを細かく見ていくと、6つのアニメーションに分解できます。
このときanimation-nameに分かりやすい名前を付けておくこと。

css
@keyframes opacity_0-1 {
    0% { opacity: 0; }
  100% { opacity: 1; }
}

@keyframes opacity_1-0 {
    0% { opacity: 1; }
  100% { opacity: 0; }
}

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

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

@keyframes bg_black-red {
    0% { background: #000; }
  100% { background: #f00; }
}

@keyframes scale_1-14 {
    0% { transform: scale(1); }
  100% { transform: scale(1.4); }
}

2.覚えておくプロパティーは5つ

プロパティーは基本的にショートハンドを用いて、下記の形で覚えておけばOK。
またカンマ区切りでアニメーションを複数指定できることも忘れずに。

css
div {
  animation:
    anime01 2s ease 0s forwards,
    anime02 2s ease-out 1s forwards;
}
// name, duration, timing-function, delay, fill-mode

name: @keyframesで付けた名前
例) opacity_0-1

duration: アニメーションの継続時間
0.5s = 0.5秒
1s = 1秒

timing-function: イージング
ease linear ease-in ease-out cubic-bezier() の中から選択

delay: アニメーションの開始を遅らせる時間
0.5s = 0.5秒
1s = 1秒

fill-mode: アニメーションの実行の前後にどう対象にスタイルを適用するかを設定
基本的に forwards (アニメーション後のスタイルを保持する)でOK

3.分解した@keyframesを組み立てていく

durationとdelayの値を調整しながら、連続したアニメーションを組み立てていく。
イージングなども個別に設定しやすい。

css
div {
  animation:
    translateY_0-50 0s ease 0s forwards,
    opacity_0-1 0.5s ease 0s forwards,
    translateY_50-0 0.5s ease 0s forwards,
    bg_black-red  0.5s ease 0.5s forwards,
    opacity_1-0  1s ease-out 1s forwards,
    scale_1-14  1s ease-out 1s forwards;
}

See the Pen roMBXx by kiti-net (@kiti-net) on CodePen.

注意

同じプロパティのアニメーションを同時に指定すると、後から実行した値に上書きされてしまうので注意。
scale と translate などの transform を同時に行いたい場合は、専用の@keyframesを用意すること。

css
// NG
div {
  animation:
    translateY_50-0 1s ease 0s forwards,
    scale_1-14  1s ease 0s forwards;
}

// OK
div {
  animation: scale_1-14_translateY_50-0 1s ease-out 0s forwards;
}

@keyframes scale_1-14_translateY_50-0 {
  0% {
    transform: scale(1) translateY(50);
  }
  100% {
    transform: scale(1.4) translateY(0);
  }
}

まとめ

複雑なアニメーションを作る際は、
0%〜100%の小さなkeyframesをたくさん作って組み立てていくことで、
直感的にアニメーション制作がおこなえるようになります。

覚えることもことも少ないので、
これから@keyframesを覚えようという人、@keyframesめんどくさいと挫折した人もぜひぜひ。

Webサイトでアニメーションを実装するには、
・単一で簡単なアニメーションはCSS transition
・連続した複雑なアニメーションはCSS @keyframes

アニメーション発火の制御に関しては、また別のお話。