サイトロゴ

Enjoy Creating
Web & Mobile Apps

MENU BOX
WEB
MOBILE
OPEN

ホーム

 > 

 > 

CSSアニメーションの基本

CSSアニメーションの基本

この記事にはプロモーションが含まれています。

Webデザインと紙面デザインは共通することも多いですが、異なる点も色々あります。
その代表が、Webページはデジタルなのでアニメーションをつけることができるという点ではないでしょうか?

アニメーションというと、細かいプログラムが必要なのではないかと身構えてしまう方もいるかもしれませんが、シンプルなアニメーションであればごく単純なCSSで実装することが可能です。
例えば以下のアニメーションはたった6行のCSSの記述で実装されています。

アニメーションをつけたサンプル画像

6行のCSSコードの中には、 { } なみかっこ が1つだけという行もあるので、実質的なコード量はもっと少ないと言えます。
他のCSS調整と違った複雑さや難しさが全くないとは言いませんが、イメージだけで「自分には無理そう…。」と思い込んでしまうのはもったいないです。

この記事ではCSSアニメーションの基本に的を絞って、余計な情報を省いて必要なポイントだけお伝えしていきます。
シンプルなアニメーションであれば、この記事の内容を把握しておくだけOKです。

アニメーションの多用・乱用はWebページ閲覧の邪魔になってしまうので注意が必要ですが、アニメーションをうまく使うことでテキストや情報量が多くても飽きにくいページデザインにすることもできます。
なのでぜひ、CSSアニメーションの基本をマスターしてきましょう!

※この記事で紹介するアニメーションは、JavaScriptと組み合わせずCSSのみで実装する場合を想定しています。
よって、スクロールさせて要素が画面内に現れると同時にアニメーションを開始する…といった制御を利用するアニメーションには当てはまらない解説・テクニックが含まれます。

– 目次 –

CSSアニメーションの基本

animationプロパティ

CSSでアニメーションを実装するにあたり使用するプロパティは、アニメーションに関するCSSを一括指定できるanimationプロパティです。
もちろん、一括指定せずにアニメーションに関するCSSプロパティを個別に指定しても良いのですが、この方法だと行数が増えてコードが煩雑になるのでおすすめはしません。

animationプロパティは、animation-name, animation-duration, animation-timing-function, animation-delay, animation-iteration-count, animation-direction, animation-fill-mode, animation-play-stateプロパティを一括で指定できるCSSプロパティです。

…こんなにあるの?という感じですが、安心してください。
8つあるCSSプロパティのうちシンプルなアニメーションで必要なのは、

  1. ・animation-name
  2. ・animation-duration
  3. ・animation-timing-function
  4. ・animation-iteration-count
  5. ・animation-direction

…の5つです。アニメーションの動きにそこまでこだわらないのであれば、さらに減らすことも可能です。
いずれにせよ、8つ全てを指定する必要はありません。

また、指定がほぼ必須なプロパティに関しても、値の種類は実質的に1つ(それ以外の値は詳しく知らなくて良い)というものも多いです。

それでは、指定がほぼ必須の5種のプロパティについて、それぞれの役割を確認してしていきましょう。

プロパティ説明
animation-nameどのアニメーションを適用させるかを指定するため、アニメーションに任意の名前を指定する。要素にクラス名をつけるようなもの。
animation-durationアニメーションが完了するまでの時間を指定。
animation-timing-functionアニメーションの進行速度変化を指定。
animation-iteration-countアニメーションが繰り返される回数を指定。
animation-directionアニメーションの再生方向を指定。

余計な情報を省くため、各プロパティの詳しい説明はここではしません。
つまり、シンプルなアニメーションを実装する上で特に詳しく知る必要もないということです。

ここで重要なのは、シンプルなCSSアニメーションを実装する上では多くの場合、animation-iteration-countとanimation-directionの値は1種類しか知らなくても問題ない(=ほぼ1種類しか使わない)ということです。
その理由は後の章で説明するので今は置いておくとして、先に進めましょう。

animation-timing-functionに関してもアニメーションの動き方にそこまでこだわらないのであれば、使う値はほぼ1〜2種類に絞れます。

animation-durationは、アニメーションの開始〜完了までにかかる時間を指定するだけなので、何も難しいことはありません。

animation-nameに至っては、要素にclass名をつけるのと同じ要領で好きなアニメーション名をつけるだけです。

よって、各プロパティの指定は実質的に以下のように言い換えることができます。

プロパティポイント
animation-name好きな名前をつけるだけ
animation-duration時間を指定するだけ
animation-timing-functionこだわらなければ1〜2種類知っておけばOK
とりあえず開始〜終了まで一定の動きになるlinearだけ押さえておけば大丈夫
animation-iteration-count永遠に繰り返すinfiniteの1種類だけでOK(値が固定)
animation-direction順方向⇔逆方向の向きになるalternateの1種類だけでOK(値が固定)

どんなアニメーションにするかはさておき、
・sample_animationというアニメーション名をつけたアニメーションを(animation-name: sample_animation)
・5秒かけてアニメーションが起こるようにして(animation-duration: 5s)
・開始〜完了まで一定の速さで動くようにして(animation-timing-function: linear)
・そのアニメーションを永遠に繰り返して(animation-iteration-count: infinite)
・開始〜完了までのアニメーションの繰り返しの方向を、順方向→逆方向にする(animation-direction: alternate)
…という指定を画像要素にしたものが以下のコードになります。


      img {
        animation: sample_animation 5s linear infinite alternate;
      }

というわけで、なんとたったの1行でアニメーションに関する指定が完了してしまいました。
あとはどんなアニメーションにするか=どんな動きをつけるかを指定する必要がありますが、それは次の章で紹介する@keyframesというCSSの記述の中に、お馴染みのCSSプロパティ(widthやheight、color、transformなど)でどのように動かしたいか、変化を加えたいかを指定すれば良いだけです。
なので、animationプロパティの指定が完了した時点で、アニメーション実装の5〜6割は完了した状態であると言えます。

それでは次の章でアニメーションの動きを指定して、実際に要素にCSSアニメーションを実装してみましょう。
アニメーション実装の完了まであと一歩です!

    POINT!
  1. ・animationプロパティでアニメーションに関するCSSを一括で指定できる!
  2. ・animationプロパティで指定できる種類は8つあるが全てを指定する必要はなく、基本的に5つだけで良い!
  3. ・animation-iteration-countとanimation-directionに該当する値は、1つだけ押さえておけばOK!

@keyframesとは

@keyframesとは、animationプロパティで指定したanimation-nameに、どのような動き(変化)を付けるかを記述するための指定です。

@keyframesは、言わばCSSの一部(文法・書き方)なので、記述する場所も他のCSS調整と同じCSSファイル内でOKです。
JavaScriptなどのように、CSSとは分類が異なるプログラム言語を扱うものではありません。
アニメーションと言うと外部のプログラムライブラリやプラグインを読み込まないといけないイメージがあるかもしれませんが、シンプルなアニメーションであれば、全てCSSで完結できます。

@keyframesは以下のような書き方をします。

@keyframesの書き方

0%{ }に記載したものがアニメーション開始時点の状態になり、100%{ }がアニメーション完了時点の状態になります。
上の例では、右に10度傾いた状態から左に10度傾く動きのアニメーションになります。

注意点としては、{ } なみかっこ をつけなければならない部分が多いため、{ }の付け忘れに気を付けましょう。

animationプロパティと組み合わせると以下のようなコード・表示結果になります。


      <img src="https://web-de-asobo.net/wp-content/uploads/2021/11/cat.jpg" alt="猫の写真">

      img {
        animation: sample_animation 5s linear infinite alternate;
      }
      @keyframes sample_animation {
        0% { transform: rotate(10deg); }
        100% { transform: rotate(-10deg); }
      }

*表示結果*

animationと@keyframesを指定した画像

というわけで、早くもアニメーションを実装することができました。

animationプロパティだけではどのような動き(アニメーション)にするのかの指定がないので、当然ですがアニメーションは起こりません。
同様に、@keyframesだけではアニメーションに関する基本設定がなされていないため、やはりアニメーションは起こりません。

つまり、animationプロパティと@keyframesは2つで1セットであると言えます。

CSSコードの記述も、animationプロパティの指定と@keyframesはできるだけ続けて(もしくは近い位置に)記述した方が分かりやすいと思います。


また、0%と100%の間にアニメーションの動きを追加することも可能です。
例えば、アニメーション開始地点(0%)から終了地点(100%)までの間のうち、ちょうどその中間点(50%)にアニメーションの動きを追加したい場合は以下のようになります。
※下の例では、50%地点に回転(rotate)の動きに加えて、拡大縮小(scale)をtransformプロパティの値に追加しています。


      <img src="https://web-de-asobo.net/wp-content/uploads/2021/11/cat.jpg" alt="猫の写真">

      img {
        animation: sample_animation 5s linear infinite alternate;
      }
      @keyframes sample_animation {
        0% { transform: rotate(10deg); }
        50% { transform: rotate(0deg) scale(.7); }
        100% { transform: rotate(-10deg); }
      }

*表示結果*

animationと@keyframesを指定した画像

※画像を回転させているtransform: rotate( );についての記事は、こちらをご覧下さい。

    POINT!
  1. ・@keyframesは、animationプロパティで設定したanimation-nameに動きや変化を加えるためのもの!
  2. ・0%がアニメーション開始時点の状態、100%が完了時の状態!
  3. ・アニメーションを起こすには、animationプロパティと@keyframesの両方の指定(記述)が必要!

アニメーションの速度変化を変更

アニメーションの進行速度変化を指定するCSSプロパティは、animation-timing-functionであり、これはanimationプロパティで一括指定することが可能でしたね。
これまでの例では、進行速度が一定になるlinearを使っていました。

多くの場合、linearで問題はありません。
これから紹介するeaseとかease-outにすると速度変化が一定ではなくなるので、シンプルなアニメーションでは不自然になることも多いからです。
ただし、たとえばボールが地面に落ちるアニメーションなど重力や慣性がはたらくようなアニメーションでは、アニメーションが一定の速度(linear)では違和感が出てしまうということになります。

アニメーションに関連するプロパティは多くて複雑なので、できるだけ把握するCSSを少なく留めておくのが良いですが、animation-timing-functionに関するCSSだけはある程度押さえておいて損はありません。

というわけで、下の表にanimation-timing-functionに該当する値とその説明をまとめました。

説明
linear開始〜終了まで一定の速度になる。
ease中間点(50%)に向けて速くなり、終了に向けて減速する。初期値。
ease-inゆっくり始まり、終了まで加速する。
ease-out速く始まり、終了に向かって減速する。
ease-in-outゆっくり始まり、速度を上げつつ、終了に向かって減速する。

例えば、速く始まり、終了に向かって減速するという効果を持つease-outを指定したアニメーション例がこちら▼です。

▲animation-timing-functionをease-outにすることで、ボールが壁に跳ね返っているみたいなアニメーションになりましたね。
ちなみにですが、上のアニメーションのHTML/CSSコードは以下のようになっています。

    <div class="sample_animation_box">
      <div class="sample_animation_ball"></div>
    </div>

    .sample_animation_box {
      width: 90%;
      padding: 5%;
      background-color: whitesmoke;
      margin: 3rem auto;
    }
    .sample_animation_ball {
      width: 5vw;
      height: 5vw;
      background-color: rgb(82, 191, 210);
      border-radius: 50%;
      padding: 40px;
      animation: sample_ball_move 4s linear infinite alternate;
    }
    @keyframes sample_ball_move {
      0% { transform: translate(0vw); }
      100% { transform: translate(50vw); }
    }

それぞれの違いを体感できるように、上にはanimation-timing-function: linear;で固定したものを、下にはanimation-timing-functionの値を切り替えられるサンプルを並べてみました。

効果を切り替えて、違いを確かめてみてくださいね!

animation-timing-functionの初期値はeaseなので、開始〜終了まで一定の速度にしたい場合は、animationプロパティで一括指定する際に、linearへの指定切り替えが必要です。
シンプルなアニメーションの場合は、基本的にlinearを指定しておけば良いという認識で大丈夫です。

少し凝った動きにしたい場合は、linear以外を色々と試してみると良いかなと思います。

    POINT!
  1. ・アニメーションの速度変化を変更したい場合は、animation-timing-functionの値を変えれば良い!
  2. ・重力や慣性が働くアニメーションでは、速度変化があった方が違和感がなくなる!
  3. ・初期値はeaseなので、一定の速度にしたい場合はlinearへの指定値変更が必要!

infiniteとalternateだけで良い理由

さて、この章ではアニメーションの実装方法ではなく、animation-iteration-countに該当する値はinfinite、animation-directionに該当する値はalternateを知っておくだけで良いと書いた理由について説明していきます。
興味がある方はご覧ください。


*animation-iteration-countはinfiniteで良い理由

animation-iteration-countはアニメーションを繰り返す回数を指定するものですが、1回とか2回とか回数を決めてしまうと、ユーザーがアニメーションを設定しているところにたどり着く前に、アニメーションが終了してしまうという可能性が出てきます。

JavaScriptを利用すれば、ユーザーがページをスクロールさせた量を計測し、画面内にアニメーションを設定している要素が含まれた時にアニメーションを開始させる…ということも可能ですが、スクロール量をCSSだけで計測することは今のところできません。
なので、CSSだけで設定しているアニメーションを確実にユーザーに見てもらうためには、アニメーションを無限に繰り返す必要がある…というわけです。


*animation-directionはalternateで良い理由

アニメーションを無限に繰り返すということは、一度きりで完結してしまうようなアニメーションだと不自然になるということです。

必然的に、上下や左右の往復移動や、拡大⇔縮小、一定の範囲内で回転させる…など、繰り返しても不自然のない動きにする必要があります。
そして、アニメーションの繰り返しが最も自然になるのが、順方向⇔逆方向になるaltarnateというわけです。

仮にalternateではなく初期値のnormalだと、下のようなかなり不自然な繰り返しアニメーションになってしまいます。

animationと@keyframesを指定した画像

もちろんこの原則は、CSSのみでアニメーションを実装し、JavaScriptを使ってアニメーションを制御しない場合に限ったものです。
プログラムでアニメーションのタイミングや開始条件を制御して、もっと複雑なアニメーションを取り入れたい場合は、animation-iteration-countやanimation-directionの値も変更する必要が出てきます。


※余談ですが、animationプロパティの一括指定でanimation-delay(アニメーション開始のタイミングを時間で指定する)を指定しなくて良い理由も同じです。
何秒後にユーザーがページのどの部分を閲覧しているかなんて予測できないので、CSSだけでアニメーションを実装する場合には指定する意味がほとんどありません。

    POINT!
  1. ・JavaScriptでアニメーションの発火条件などを制御しない場合、アニメーションの回数は無限にする必要がある!
  2. ・無限にアニメーションを繰り返すのであれば、繰り返しても不自然ではない動き(向き)にする必要がある!
  3. ・プログラムでアニメーションを制御する場合はこの限りではないのでご注意を!

今回の動画で紹介したコード!

今回の解説動画で使用したコードを掲載しています。学習用としてご自由にコピペしてお使い下さい。(※スクロールできます)

<!DOCTYPE html>
<html lang="ja" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title></title>
    <style>
    img {
      display: block;
      margin: 0 auto;
      animation: sample_animation 4s linear infinite normal;
    }
    @keyframes sample_animation {
      0% { transform: scale(1); }
      100% { transform: scale(1.5); }
    }

    .sample_animation_box3 {
      width: 90%;
      padding: 5%;
      background-color: whitesmoke;
      margin: 3rem auto;
    }
    .sample_animation_ball3 {
      width: 5vw;
      height: 5vw;
      background-color: rgb(82, 191, 210);
      border: solid black;
      border-radius: 50%;
      padding: 40px;
      animation: sample_ball_move 4s linear infinite alternate;
    }
    @keyframes sample_ball_move {
      0% { transform: translate(0vw); }
      100% { transform: translate(50vw); }
    }

    .sample_animation_box2 {
      width: 90%;
      padding: 5%;
      background-color: whitesmoke;
      margin: 3rem auto;
    }
    .sample_animation_ball2 {
      width: 5vw;
      height: 5vw;
      background-color: rgb(82, 191, 210);
      border: solid black;
      border-radius: 50%;
      padding: 40px;
      animation: sample_ball_move2 4s linear infinite alternate;
    }
    @keyframes sample_ball_move2 {
      0% { transform: translate(0vw); }
      100% { transform: translate(50vw); }
    }
    .animation_timing_function_sel {
      display: block;
      margin: 2rem auto;
      font-size: 24px;
    }

    </style>
  </head>
  <body>
    <div style="height: 400px;"></div>

    <img src="https://web-de-asobo.net/wp-content/uploads/2021/11/cat.jpg" alt="猫の写真" width="300">

    <div style="height: 400px;"></div>

    <div class="sample_animation_box3">
      <div class="sample_animation_ball3"></div>
    </div>

    <div class="ample_animation_box2_outer">
      <div class="sample_animation_box2">
        <div class="sample_animation_ball2"></div>
      </div>
      <select class="animation_timing_function_sel" name="">
        <option value="linear" selected>linear</option>
        <option value="ease">ease</option>
        <option value="ease-in">ease-in</option>
        <option value="ease-out">ease-out</option>
        <option value="ease-in-out">ease-in-out</option>
      </select>
    </div>

    <div style="height: 400px;"></div>

    <script type="text/javascript" defer="">
      {
        const sample_animation_ball2 = document.querySelector('.sample_animation_ball2');
        const animation_timing_function_sel = document.querySelector('.animation_timing_function_sel');

        animation_timing_function_sel.addEventListener('change', ()=> {
          let selectedValue = animation_timing_function_sel.value;
          sample_animation_ball2.style.animationTimingFunction = selectedValue;
        });
      }
    </script>

  </body>
</html>

« »

カテゴリーリンク

著者について- author profile -

ROYDOプロフィール写真
Michihiro

モバイルアプリ(iOS・Android)ディベロッパー&デザイナー

これまでに、可読性の高いカラーパターンを自動で生成するアプリや、『第3火曜日』といった形式で通知をスケジュールできるアプリなどを制作。

サブでWebデザイン・フロントエンドエンジニアとしても活動しています。

📝ツール・言語:JavaScript/React Native/Kotlin/Android Studio/Swift/SwiftUI

🎓資格:基本情報技術者/ウェブデザイン技能検定3級

Twitterアイコン Instagramアイコン