【CSS】 animationとkeyframeの種類

CSSでは、transition以外にもkeyframeを用いた複雑なアニメーションを作成できます。どの時間帯にどのような状態なのかを細かく指定できます。

animationの方法

CSSでアニメーションするには、keyframesanimationプロパティの2つを組み合わせます。

keyframesでどのような時刻にどのような状態かを指定し、animationプロパティで時刻の変化の仕方を指定します。

See the Pen css animation keyframe by Totori (@souki202) on CodePen.

keyframes

keyframesには、時刻ごとの状態を指定します。時刻はパーセンテージで指定します。つまり、0%はアニメーション開始の時刻、100%はアニメーション終了の時刻ということです。

例えば、

@keyframes slidein {
    0% {
        margin-left: 0;
    }
    100% {
        margin-left: 300px;
    }
}

とすると、開始した瞬間はmargin-left: 0;の状態、終了時にはmargin-left: 300px;の状態になります。

0%の代わりにfrom, 100%の代わりにtoと書くこともできます。

keyframeを増やす場合も同様にパーセンテージを指定します。

@keyframes slidein {
    0% {
        margin-left: 0;
    }
    75% {
        margin-left: 400px;
    }
    100% {
        margin-left: 300px;
    }
}

上の例だと、75%のタイミングでは400px分移動し、100%のタイミングで300pxに戻る、という動作になります。

animationプロパティ

animationプロパティは非常に多くの指定方法があるため、いくつかのパターンだけ把握しておくと良いです。下で紹介するもの以外にも、識別できる内容と順序であれば動作します。

p {
    /* アニメーション時間 | アニメーション種類 | 最初のアニメーションまでの待ち時間 | ループ回数 | 時刻の向き | 開始と終了の状態 | 再生の状態 | keyframes名 */
    animation: 3s ease-in 1s infinite normal both running slidein;

    /* keyframes名 | 時間 | 種類 | 開始待ち時間 */
    animation: slidein 3s linear 1s;

    /* keyframes名 | 時間 | 種類 | ループ回数 */
    animation: slidein 3s ease-in infinite;

    /* keyframes名 | 時間 */
    animation: slidein 3s;
}

複数のアニメーションを指定する場合はカンマで区切ります。

p {
    /* keyframes名 | 時間 */
    animation: slidein 3s, bigger 1s;
}

ここで、複数のアニメーションを指定した場合、それぞれのアニメーションは完全に別々のパラメータで再生されます。再生自体は同時にできますが、アニメーションの状態の管理は別々ということです。

個別指定

他のCSSのプロパティと同じように、それぞれの値は個別で指定できます。

animation-name

アニメーション名を指定します。これは、keyframesに付けた名前を指定します。

p {
    animation-name: sample-anim;

    /* 複数のアニメーションを使用する */
    animation-name: sample-anim, test-1;
}

animation-duration

アニメーションの時間を指定します。

p {
    animation-duration: 3s;
    animation-duration: 200ms;

    /* sample-animが3s, test-1が100ms */
    animation-name: sample-anim, test-1;
    animation-duration: 3s, 100ms;
}

animation-timing-function

アニメーションの種類です。線形に変化するのか、最初はゆっくりでだんだん早くなるのかなどを指定できます。これはtransitionに指定したものと同じ挙動になります。

細かいアニメーションの動きは下の記事を参考にしてください。

p {
    animation-timing-function: ease; /* 完了と終了がなめらか */
    animation-timing-function: ease-in; /* ゆっくり始まる */
    animation-timing-function: ease-out; /* ゆっくり終わる */
    animation-timing-function: ease-in-out; /* ゆっくり始まり, ゆっくり終わる */
    animation-timing-function: linear; /* 一定の速度 */
    animation-timing-function: step-start; /* アニメーション開始直後に変化 */
    animation-timing-function: step-end; /* アニメーション終了時に変化 */

    animation-timing-function: steps(4, jump-start); /* 開始時に最初のジャンプ */
    animation-timing-function: steps(10, jump-end); /* 終了時に最後のジャンプ (1回目のジャンプが遅れる) */
    animation-timing-function: steps(20, jump-none);/* startとendの中間のタイミングでジャンプ */
    animation-timing-function: steps(5, jump-both); /* 1回目が少し遅れ(jump-endと同じ), 最後が止まった状態で終わる(jump-start) */
    animation-timing-function: steps(6, start); /* jump-startと同じ */
    animation-timing-function: steps(8, end); /* jump-endと同じ */
    animation-timing-function: steps(6, step-start); /* jump-startと同じ */
    animation-timing-function: steps(8, step-end); /* jump-endと同じ */

    animation-timing-function: cubic-bezier(0.1, 0.7, 1.0, 0.1); /* ベジェ曲線で指定 */
}

ここで、linear以外を指定したときに注意があります。

linear以外では開始が遅い、終了が遅いなどあります。このとき、アニメーションは0~100%がそうなるのではなく、各keyframeごとにそのような挙動になります。

See the Pen Untitled by Totori (@souki202) on CodePen.

カクカクしていますね。各keyframe間でease-inの挙動になっています。現状は回避する方法はないため、区切る際は全く区切らないようにするか、linearにした上でたくさん区切って動きを近似するなどの工夫が必要です。アニメーション量や速度によりますが、6分割くらいしておけばlinearease系の動きを近似してもほぼ気が付きません。

animation-delay

アニメーションが開始するまでの時間です。ループしてからは無視されます

また、負数を指定するとアニメーションの途中から開始することができます。

p {
    animation-delay: 3s;
    animation-delay: 100s;
    animation-delay: 0;

    /* 2秒経過した時点からスタート */
    animation-delay: -2s;
}

animation-direction

アニメーションの再生の方向です。普通に再生なのか、逆再生なのか、再生と逆再生を繰り返すのか、などを指定できます。

See the Pen css animation direction by Totori (@souki202) on CodePen.

p {
    animation-direction: normal;
    animation-direction: reverse;
    animation-direction: alternate;
    animation-direction: alternate-reverse;

    /* アニメーションが複数の場合 */
    animation-direction: normal, alternate;
}
意味
normal順方向に再生
reverse逆方向に再生。アニメーションの種類 (ease-outなど) も全て逆再生状態になります。
alternate順方向と逆方向を交互に再生
alternate-reverse逆方向と順方向を交互に再生

animation-iteration-count

ループ回数を指定します。0の場合は一度も再生されず、infiniteなら無限にループします。1.5などの小数がついたら、アニメーションは途中で終わります。つまり、1.5なら2回目のちょうど半分まで再生が行われます。

p {
    animation-iteration-count: infinite;

    /* 再生しない */
    animation-iteration-count: 0;

    /* 初期値 */
    animation-iteration-count: 1;

    /* 2回と、3回目の40%地点まで再生 */
    animation-iteration-count: 2.4;

    /* 複数のアニメーションがある場合 */
    animation-iteration-count: 1, 2, 2.4;

}

animation-fill-mode

アニメーションの実行前後にどのような状態になっているかを指定します。この状態には、アニメーションの方向が影響します。

forwardsの場合、最後の状態が計算されます。順方向なら最後(100%)、逆方向なら最初(0%)が最終的な状態になります。主にループが完全に終了後に影響します。

backwardsの場合、最初の状態が計算されます。順方向なら最初(0%)、逆方向なら最後(100%)が最初の状態になります。これは、主にanimation-delayが指定されているときに影響します。

bothの場合、forwardsbackwards両方が適用されます。

デフォルトはnoneです。noneは、アニメーションの状態ではなく、その他のCSSの状態で決まります。(つまり、アニメーションが終わったらアニメーションの状態は破棄される)

p {
    animation-fill-mode: none;
    animation-fill-mode: forwards;
    animation-fill-mode: backwards;
    animation-fill-mode: both;
}

See the Pen css animation fillmode by Totori (@souki202) on CodePen.

再生がalternateの場合は、アニメーションが終わったときの再生の方向によって決まります。

animation-play-state

再生しているか、停止しているかを指定します。ここで、停止や再生時に時間は戻りません。

p {
    /* 停止 */
    animation-play-state: paused;

    /* 再生 */
    animation-play-state: running;
}

See the Pen css animation playstate by Totori (@souki202) on CodePen.

アニメーションサンプル

下の例は、複数のアニメーションを使用した例です。光っている部分は四角いブロック要素ですが、それのscaleの変化とopacityの変化を別々でアニメーションさせています。

See the Pen practice button2 by Totori (@souki202) on CodePen.

まとめ

複数のアニメーションを組み合わせたり、hover時にだけアニメーションを付けるなどで、非常に高度なアニメーションをCSSだけで組むことができます。少し複雑ですが、重要なプロパティなので使えるようになりましょう!

css animation thumb

役に立ったらシェアしよう!