Help us understand the problem. What is going on with this article?

CSSアニメーションを使いこなすために知っておきたい5つのこと

More than 3 years have passed since last update.

はじめに

keyframesを使ったCSSアニメーションは描画パフォーマンスが良く、ヌルヌルな動きが簡単に実装できます。
最近旧IEのサポートが切られたこともあり、今後は触る機会もより増えてくるかと思います。

そこでCSSアニメーションをガリガリ使っていく上で、これは覚えておきたい!と思ったことをまとめてみました。何かの参考にでもなれば幸いです。

  • 基本的なプロパティや使い方などは省略します
  • サンプルコードではprefixを省略しています
  • 5つとは単に私が思いついた数なので、深い意味はありません

目次

  • はじめに
  • 複雑なイージングはChrome Devtoolsで簡単に実装できる
  • イージングはkeyframesの中で細かく再定義できる
  • カンマ区切りでシーケンシャルに表現する
  • コマ送りアニメーションにはsteps()が便利
  • アニメーションのcallback(イベント)を取得する
  • 終わりに

複雑なイージングはChrome Devtoolsで簡単に実装できる

デフォルトで用意されているイージングの値は、ease, linear, ease-in, ease-out, ease-in-outなど多くはありません。jQueryプラグインなどで用意されているような複雑なイージングはcubic-bezier()を使えば実現可能ですが、3次ベジェ曲線なので調整が大変です。

そこでChrome Devtoolsの機能を使えば、直感的にcubic-bezier()を生成することができます。
(生成してくれるプリプロセッサやオンラインサービスもあります)

Devtoolsを使ったcubic-bezier()生成については、過去投稿した記事で簡単に説明しています。詳細は以下をご覧ください。
知っていると幸せになれるかもしれないChromeDevtoolsの小技集 ~CSS開発編~ #イージングの簡単設定

イージングはkeyframesの中で細かく再定義できる

イージングはanimation-timing-functionを使って定義しますが、このプロパティはkeyframesの中で再定義が可能です。上手く使えばシンプルなコードで複雑なアニメーションが実装できます。

keyframeの中でイージングを再定義.css
div {
  background-color: red;
  height: 20px;
  width: 20px;
  animation: 'bounce' 2s ease-out 0s infinite alternate;
}

@keyframes bounce {
  from {
    margin-top: 100px;
    animation-timing-function: ease-out;
  }
  25% {
    margin-top: 50px;
    animation-timing-function: ease-in;
  }
  50% {
    margin-top: 100px;
    animation-timing-function: ease-out;
  }
  75% {
    margin-top: 75px;
    animation-timing-function: ease-in;
  }
  to {
    margin-top: 100px;
  }
}

[動作イメージ]
anim1.gif

カンマ区切りでシーケンシャルに表現する

複数のアニメーションを自由に組み合わせたい!
決まった順番にアニメーションを実行したい!

アニメーションのイベントはjavaScriptで取得できるため、jsと組み合わせて実装することが多いかと思います。
が、単純なものであればカンマ区切りとanimation-fill-modeを使ってCSSだけでも表現可能です。

シーケンシャルなアニメーション.css
div {
  background-color: red;
  height: 20px;
  width: 20px;
  animation:
    'h' 1s ease 0s alternate forwards,
    'w' 1s ease 1s alternate forwards,
    'h' 1s ease 2s reverse forwards,
    'w' 1s ease 3s reverse forwards;
}

@keyframes h {
  from { height: 20px;}
  to   { height: 100px;}
}
@keyframes w {
  from { width: 20px;}
  to   { width: 100px;}
}

[動作イメージ]
anim2.gif

ポイント

  • animationの値をカンマ区切りで並べることで、複数のアニメーションを同時に設定しています
  • animation-fill-mode: forwards; を指定することで、直前に設定した値を引き継いで次のアニメーションの実行ができます
  • animation-delay: ;で各アニメーションの発動タイミングをずらし、あたかも順番を守っているかのように見せることができます

delayの値を調整することで「これとこれは同時に実行して」「これはその後に実行する」といった多少複雑なことも可能です。またkeyframesの粒度を小さくすることもできるので、コードをシンプルにできるかもしれません。(prefixも考えると出力コードは増えそうですが)

コマ送りアニメーションにはsteps()が便利

CSS transitionであればプロパティを指定することで、アニメーションさせたいプロパティを制限することができます。しかしkeyframesは基本的に動かせるものは全てアニメーションしてしまいます。コマ送りやパラパラと切り替えたい場合には、animation-timing-functionのsteps()が便利です。

stepsを使ったコマ送りアニメーション.css
div {
  background-color: red;
  height: 20px;
  width: 20px;
  animation: 'parapara' 0.5s steps(2, start) 0s infinite alternate;
}

@keyframes parapara {
  from { height: 20px;}
  to   { height: 50px;}
}

[動作イメージ]
anim3.gif

steps()については、過去投稿した記事で簡単に説明しています。詳細は以下をご覧ください。
はじめよう!スプライトアニメーション #cssだけで表現してみる

アニメーションできない指定を使う

スプライトのようにbackground-positionで値を操作するのではなく、画像自体を差し替えてしまえばsteps()を使わずともコマ送りを実現させることができます(というか動かせない)。

画像を差し替えてコマ送りアニメーション.css
div {
  height: 16px;
  width: 16px;
  animation: 'switchIcon' 1s ease 0s infinite;
}

@keyframes switchIcon {
  from {
    /* アイコン画像1 */
    content: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAArUlEQVQ4T8WTIQ6DQBBFHw6JxMFRkD1GZWUdskUicZUcoUfoUYqrrEQ2P5lNtruFbAVh1CQ78+f/+TsZy1ECR+AA3IEReIfl2QqAnq7ABegsj8o3BZAETT8BN2PxSpWg5taac2A2kB74AlmScLbphTdRC9ROBp/FL4DamuVAGHJCC326h00BGmDyKFTA4x8GapZmF8oFkixhfwBR19ZdOFeSJexno38D4UeKbuID1HczERkBWZYAAAAASUVORK5CYII=');
  }
  to {
    /* アイコン画像2 */
    content: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABEklEQVQ4T63TLzPEURTG8c8mokb0ChBFTWQUfwqNRqMZjegd0GiGItIohiZSDE1ciXl2zu6sHWOM3VPu/H73nu99znPObegzGn3mGxhguJQ0a833JKYxgidc1/pNdBTkwDrGcIhAtrGBNjhJj9jHKeYxk58BrGEO7wVYxBZucIEXTGAZr9iryzqAo5J7j1usFuwZsxjHGd7qohN81LmWgiSO4hJJCuCuCl3o8uaqSoqKB0RpM4DPOhQlvwFi4lCVcVyAloLUG6kh/7WEADbbJsaMyE6kC0u1GRPPu0xc6TIxHdn9CRCH08adam1vGw8QE9PyDiBzkIFJxKgAkjjVM0jZy0Alst9pY1/PYWBv4d8qvgBJr0W7oeYU2wAAAABJRU5ErkJggg==');
 }
}

[動作イメージ]
anim4.gif

[補足]
colorをsteps()で制御する場合、途中の色が適用されてしまうのか指定した色を正しく表現してくれません。ちょっと回避策が思いつかなかったので、steps()で色の変更を行う際はご注意ください。※対応策があればご教授ください。

色が正しくでないコマ送りアニメーション.css
div {
  height: 20px;
  width: 20px;
  animation: 'switchColor' 0.5s steps(2, start) infinite alternate;
}
@keyframes switchColor {
  from { background-color: blue;}
  to   { background-color: red;}
}

[動作イメージ]
anim5.gif
※blueが紫になってしまっている

アニメーションのcallback(イベント)を取得する

すでに触れていますが、javaScriptによってアニメーションのイベントを取得することができます。

  • animationstart(delay完了後)
  • animationend(終了後)
  • animationiteration(反復が終わる時)

具体的なコードは以下ページを紹介させていただきます
CSS3アニメーションのイベントを取得する

終わりに

自作の関連ページ

参考サイト一覧

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした