CSS アニメーションを 1 つの例で
アニメーションは 2 つの部分でできています。段階を記述する @keyframes と、それを時間付きで要素に適用する animation プロパティです。このカードは、ページの読み込み時にスライドしながらフェードインします:
コードを編集する (または時間を 2s に変える) とプレビューが再読み込みされるので、カードがもう一度入ってくるのを見られます。@media (prefers-reduced-motion: reduce) のブロックは、システムで動きを減らす設定にしている読者に対してだけ、キーフレームをフェードのみに置き換えます。
@keyframes の書き方
@keyframes pulse {
0% { transform: scale(1); }
50% { transform: scale(1.08); }
100% { transform: scale(1); }
}
fromは0%と、toは100%と同じです。- パーセントの段階は必要なだけ追加できます。同じスタイルの段階は 1 行にまとめられます:
0%, 100% { ... }。 - 最初か最後のキーフレームにないプロパティは、要素自身の値から、または要素自身の値へアニメーションします。
- 名前 (
pulse) はanimation-nameに渡すものです。大文字と小文字が区別され、noneのようなキーワードは使えません。
animation のプロパティ
| プロパティ | 指定するもの | 初期値 |
|---|---|---|
animation-name | 実行する @keyframes | none |
animation-duration | 1 回分の長さ | 0s |
animation-timing-function | キーフレーム間の速さの曲線 | ease |
animation-delay | 最初の 1 回の前の待ち時間 (負の値で途中から始まる) | 0s |
animation-iteration-count | 繰り返しの回数、または infinite | 1 |
animation-direction | normal、reverse、alternate、alternate-reverse | normal |
animation-fill-mode | 前後のスタイル: none、forwards、backwards、both | none |
animation-play-state | running か paused | running |
ショートハンドでは、ほぼどの順番でも書けます。唯一のルールは、1 つ目の時間が duration、2 つ目が delay ということです:
.loader {
animation: pulse 1.2s ease-in-out 0.2s infinite alternate both;
/* name duration timing delay count direction fill */
}
direction と fill-mode を試す
direction、fill mode、回数を選んで Play を押してください。ボックスはトラックの終わりまで 200px 動きます。表示欄には、アニメーションが終わった後にボックスが止まった位置が表示されます:
注目してほしい点:
fill-mode: none(初期値): 最後のフレームの後、ボックスは x = 0 に戻り、また琥珀色になります。forwards: 最後のキーフレームにとどまります。normalでは x = 200 で緑、reverseでは最後に再生されたキーフレームがfromなので、x = 0 で青で終わります。alternateで回数 2 なら行って戻るので、forwardsでも x = 0 で終わります。
無限ループ: 読み込み中の表示
infinite は永遠に繰り返し、子要素ごとの animation-delay でタイミングをずらすと、順番に動きます。ループは穏やかに保ちましょう。ゆっくり、小さく、点滅はさせません。
role="status" と aria-label で、スクリーンリーダーの利用者に読み込み中であることを伝えます。点だけでは伝わりません。回転する円は rotate のページ を見てください。
アニメーションの一時停止と制御
animation-play-state: paused はアニメーションをその場で止め、running でそこから再開します。下のバーにホバーすると一時停止します:
JavaScript では、element.getAnimations() が実行中の CSS アニメーションを返します。それぞれに pause()、play()、cancel() と、読み書きできる currentTime があります。animationend イベントは無限でないアニメーションが終わったときに、animationiteration は各回の終わりに発生します。
動きを減らす設定を尊重し、点滅させない
すべてのアニメーションに、アクセシビリティのルールが 2 つあります:
- 動きを減らす設定。 動きで気分が悪くなるため、システムに動きを減らすよう設定している人がいます。一番安全なのは、動きを減らす設定をしていない人にだけ動きを加えるパターンです:
@media (prefers-reduced-motion: no-preference) {
.hero-title { animation: slide-in 0.8s ease-out both; }
}
- 点滅させない。 1 秒間に 3 回より多く点滅するコンテンツは、発作を引き起こすことがあります。速く、コントラストの高い点滅はまったく使わないようにしましょう。
アニメーションをなめらかに保つ
できるだけ transform と opacity をアニメーションさせましょう。ブラウザはページを配置し直さずにこれらを適用できるので、遅いスマートフォンでもなめらかです。width、height、top、left、margin をアニメーションさせると、毎フレームレイアウトが計算し直されます。要素を動かすには、transform のページ の translate() を使います。
よくある間違い
- 時間がない。 時間の初期値は
0sなので、animation: fade;は何もしません。 - 名前が一致しない。
animation-nameは、大文字と小文字も含めて@keyframesの名前と完全に一致する必要があります。 - 終わりに元に戻ってしまう。 最後のキーフレームを保つには
forwards(またはboth) を追加します。 - 遅延させたアニメーションが始まる前にちらつく。
animation-delayの間、要素は通常のスタイルで表示されます。backwards(またはboth) で、待ち時間の間に最初のキーフレームを適用できます。 - 同じ値を設定してアニメーションを再開しようとする。 同じ
animationをもう一度設定しても何も起きません。上の Play ボタンのように、いったん取り除き、リフローを起こし (el.offsetWidth)、もう一度設定します。 displayをアニメーションさせる。 すぐに切り替わります。代わりにopacityとtransformをアニメーションさせましょう。
よくある質問
CSS でアニメーションを作るには?
@keyframes name { from { ... } to { ... } } で段階を定義し、animation プロパティと時間で要素に適用します: animation: name 1s ease-out;。時間の初期値は 0s なので、時間の指定は必須です。
animation-fill-mode: forwards は何をしますか?
アニメーションが終わった後も、最後のキーフレームのスタイルを保ちます。これがないと、要素は通常のスタイルに戻ります。backwards は待ち時間 (delay) の間に最初のキーフレームを適用し、both はその両方をします。
CSS アニメーションを無限にループさせるには?
animation-iteration-count: infinite を指定するか、ショートハンドに infinite を加えます: animation: spin 1s linear infinite;。alternate を加えると、1 回ごとに順方向と逆方向に交互に再生されます。
CSS の animation と transition の違いは何ですか?
transition は、プロパティが変わったとき (たいていはホバーやクラスの変更) に 2 つの値の間でアニメーションさせます。animation は適用されるとすぐに自分で動き出し、キーフレームをいくつでも持てて、繰り返し、逆再生、一時停止ができます。
CSS アニメーションを一時停止するには?
要素に animation-play-state: paused を指定します。たとえば :hover や、JavaScript で追加するクラスで指定します。running に戻すと、止まったところから再開します。
動きを減らす設定の人にはアニメーションをオフにするには?
アニメーションを @media (prefers-reduced-motion: no-preference) { ... } で包むか、@media (prefers-reduced-motion: reduce) { ... } の中で取り除きます。このクエリは、ユーザーの OS の動きを減らす設定に従います。