CSSアニメーション徹底解説|@keyframes の基本から応用まで


@keyframes とは?

@keyframes は、CSS でアニメーションを作成する際に使用する規則です。アニメーションの進行状態に応じて、特定のプロパティをどのように変化させるかを指定できます。

例えば、要素の位置、色、サイズ、透明度などを時間とともに変化させることができます。


@keyframes の基本構文

@keyframes の基本的な構文は以下の通りです:

@keyframes アニメーション名 {
  0% { プロパティ: 値; }
  50% { プロパティ: 値; }
  100% { プロパティ: 値; }
}

0%: アニメーションの開始時点を示します。
50%: アニメーション進行の途中(例: 中間点)を示します。
100%: アニメーションの終了時点を示します。


@keyframes を使った具体例

簡単な例: 色の変化

以下は、背景色を変化させるアニメーションの例です。

@keyframes changeColor {
  0% {
    background-color: red;
  }
  50% {
    background-color: yellow;
  }
  100% {
    background-color: green;
  }
}

.box {
  width: 100px;
  height: 100px;
  animation: changeColor 3s infinite;
}

animation プロパティ: このプロパティでアニメーションを適用します。

  • 3s: アニメーションの時間(3秒)。
  • infinite: アニメーションを無限ループさせる。

ステップごとの変化: 複数の中間点

@keyframes では、必要に応じて任意の割合で中間点を指定できます。

@keyframes moveBox {
  0% {
    transform: translateX(0);
  }
  25% {
    transform: translateX(50px);
  }
  50% {
    transform: translateX(100px);
  }
  75% {
    transform: translateX(150px);
  }
  100% {
    transform: translateX(200px);
  }
}

.box {
  width: 50px;
  height: 50px;
  background-color: blue;
  animation: moveBox 4s ease-in-out infinite;
}

CSSアニメーションと @keyframes の組み合わせ

@keyframes を使う際には、animation プロパティで詳細な設定を行います。主なプロパティは以下の通りです:

  • animation-name: アニメーション名を指定。
  • animation-duration: アニメーションの再生時間を設定。
  • animation-timing-function: アニメーションの速度変化を指定。
  • animation-delay: アニメーション開始の遅延時間を指定。
  • animation-iteration-count: 再生回数を指定。
  • animation-direction: アニメーションの方向を指定(例: alternate)。

例: すべてのプロパティを適用

@keyframes scaleUp {
  0% {
    transform: scale(1);
  }
  100% {
    transform: scale(1.5);
  }
}

.box {
  width: 100px;
  height: 100px;
  background-color: purple;
  animation: scaleUp 2s ease-in 1s 3 alternate;
}

2s: 再生時間。
ease-in: スムーズな開始。
1s: 1秒遅延。
3: 再生回数。
alternate: 再生時に逆再生を繰り返す。


実践的な例: ボタンのホバーアニメーション

以下は、ボタンにホバー時のアニメーションを追加する例です。

@keyframes hoverShadow {
  0% {
    box-shadow: 0 0 5px rgba(0, 0, 0, 0.3);
  }
  100% {
    box-shadow: 0 0 20px rgba(0, 0, 0, 0.6);
  }
}

button {
  padding: 10px 20px;
  border: none;
  background-color: #007bff;
  color: white;
  cursor: pointer;
  animation: hoverShadow 0.5s ease-in-out infinite alternate;
}

1. animation-direction(アニメーションの方向)

animation-direction は、アニメーションの再生方向を設定するプロパティです。以下のような値を指定できます:

説明
normalデフォルトの設定。最初から最後まで再生します(通常の方向)。
reverseアニメーションを最後から最初に再生します(逆方向)。
alternate最初から最後、次に最後から最初へと交互に再生します。
alternate-reverse最初は逆方向(最後から最初)で再生し、その後、通常の方向で交互に再生します。

例: animation-direction の使い方

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

.box {
  width: 50px;
  height: 50px;
  background-color: orange;
  animation: bounce 2s ease-in-out infinite alternate;
}
  • alternate の指定により、アニメーションが上昇(0%50%)と下降(50%100%)を繰り返します。

2. animation-iteration-count(再生回数の指定)

animation-iteration-count は、アニメーションの再生回数を指定するプロパティです。以下の値を設定できます:

説明
数値(例: 1, 3アニメーションを指定回数だけ再生します。
infiniteアニメーションを無限に繰り返します。

例: animation-iteration-count の使い方

@keyframes fadeInOut {
  0% {
    opacity: 0;
  }
  50% {
    opacity: 1;
  }
  100% {
    opacity: 0;
  }
}

.box {
  width: 100px;
  height: 100px;
  background-color: lightblue;
  animation: fadeInOut 2s linear 3;
}
  • 上記の例では、アニメーションが 3 回再生された後に停止します。

3. animation-timing-function(速度変化の指定)

アニメーションの速度変化を制御するプロパティです。以下の値を指定できます:

説明
linear一定の速度で再生されます。
easeスムーズな加速と減速(デフォルト値)。
ease-inゆっくりと始まり、最後に急加速します。
ease-out初めは速く、最後にゆっくりと減速します。
ease-in-outゆっくり始まり、ゆっくり終わる(中間部分は速い)。
steps(n, start/end)指定したステップ数で変化します(例: steps(4, end))。

例: timing-function の使い方

@keyframes slideIn {
  0% {
    transform: translateX(-100%);
  }
  100% {
    transform: translateX(0);
  }
}

.box {
  width: 200px;
  height: 50px;
  background-color: lightgreen;
  animation: slideIn 3s ease-in-out infinite;
}

4. animation-fill-mode(アニメーション終了後の状態)

アニメーションが終了した後、要素の状態を制御します。

説明
noneアニメーションが終了したら、要素は初期状態に戻ります(デフォルト)。
forwardsアニメーションの最終状態を保持します。
backwardsアニメーションの最初の状態を保持します。
bothアニメーション開始前と終了後の状態を保持します。

例: fill-mode の使い方

@keyframes grow {
  0% {
    transform: scale(1);
  }
  100% {
    transform: scale(1.5);
  }
}

.box {
  width: 50px;
  height: 50px;
  background-color: pink;
  animation: grow 2s forwards;
}

5. animation-delay(アニメーションの遅延)

アニメーションの開始を遅らせる時間を指定します。

説明
0s遅延なし(デフォルト)。
数値(例: 1s, 500msアニメーション開始を遅らせる時間。

例: animation-delay の使い方

@keyframes spin {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(360deg);
  }
}

.box {
  width: 50px;
  height: 50px;
  background-color: lightcoral;
  animation: spin 2s linear infinite;
  animation-delay: 1s;
}

組み合わせた例

最後に、上記すべてを組み合わせた例を示します:

@keyframes complexAnimation {
  0% {
    transform: translateY(0) scale(1);
  }
  50% {
    transform: translateY(-50px) scale(1.2);
  }
  100% {
    transform: translateY(0) scale(1);
  }
}

.box {
  width: 100px;
  height: 100px;
  background-color: deepskyblue;
  animation: complexAnimation 3s ease-in-out infinite alternate;
}

この例では、ボックスが上下に移動しながらサイズを変化させ、スムーズに繰り返し動きます。


CSSのtransitionとanimation(@keyframes)の違い

CSSで動きをつける方法は主にtransitionとanimation(@keyframes)の2つがあります。どちらを使うべきか迷う場合は、以下の比較を参考にしてください。

比較項目transitionanimation(@keyframes)
トリガー:hoverなどの状態変化が必要自動再生が可能
中間状態開始と終了の2点のみ0%〜100%の任意のポイントを指定可能
繰り返し不可(状態変化のたびに発火)infiniteで無限ループ可能
逆再生状態が戻ると自動で逆再生animation-direction: alternateで指定
複雑さシンプルな変化に最適複数ステップの複雑な動きに対応
JavaScript連携transitionendイベントanimationstart / animationendイベント

ホバーやフォーカスなどユーザー操作に連動する単純な変化にはtransition、ページ読み込み時の自動再生や複数ステップの動きには@keyframesが適しています。


CSSアニメーションが動かないときのチェックリスト

@keyframesアニメーションが期待通りに動作しない場合、以下の原因を順番に確認してください。

  1. animation-nameのスペルミス: @keyframesで定義した名前とanimationプロパティで指定した名前が一致しているか確認する
  2. animation-durationが未指定: durationのデフォルトは0sのため、明示的に指定しないとアニメーションが一瞬で終了する
  3. display: noneの要素: 非表示の要素にはアニメーションが適用されない
  4. animationプロパティの値の順序: animation短縮プロパティでは、最初の時間値がduration、2番目がdelayとして解釈される
  5. animation-fill-modeの未指定: アニメーション終了後に要素が初期状態に戻る場合はforwardsを指定する
  6. CSSの詳細度(specificity)の競合: 他のスタイルがアニメーション対象のプロパティを!importantで上書きしている場合、アニメーションが効かない

アクセシビリティとパフォーマンスの注意点

prefers-reduced-motionへの対応

視覚的な動きに敏感なユーザーのために、OSの「視差効果を減らす」設定を尊重するCSSを追加しましょう。

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

パフォーマンスを意識したプロパティ選び

CSSアニメーションのパフォーマンスは、アニメーションさせるプロパティによって大きく変わります。

パフォーマンスプロパティ理由
高速(推奨)transform, opacityGPUで合成処理されるためリフロー不要
中速color, background-colorリペイントのみ発生
低速(避ける)width, height, margin, paddingレイアウト再計算(リフロー)が発生

要素の位置やサイズを変えたい場合は、widthやmarginではなくtransform: translate()やtransform: scale()を使うことで、60fpsのスムーズなアニメーションを維持できます。


よくある質問(FAQ)

Q. @keyframesとtransitionはどちらを先に学ぶべきですか?

transitionから学ぶのがおすすめです。transitionは「開始状態」と「終了状態」の2点を指定するだけで動きが作れるため、CSSアニメーションの基本概念を理解しやすくなります。transitionに慣れたら、複数ステップや自動再生が可能な@keyframesに進むとスムーズです。

Q. CSSアニメーションとJavaScriptアニメーションはどう使い分けますか?

単純な視覚効果(フェードイン、スライド、回転など)はCSSアニメーションで十分です。一方、スクロール位置に連動する動き、ユーザーの操作に応じた複雑な制御、物理シミュレーションなどが必要な場合はJavaScript(Web Animations APIやGSAPなど)を使います。

Q. animation-fill-mode: forwardsとbothの違いは何ですか?

forwardsはアニメーション終了後に最終フレーム(100%)の状態を保持します。bothはforwardsに加えて、animation-delayの待機中にも最初のフレーム(0%)のスタイルを適用します。delayを使わない場合はforwardsとbothの動作は同じです。

Q. CSSアニメーションでスクロールに連動した動きは作れますか?

CSS Scroll-Driven Animations(animation-timeline: scroll())を使えば、JavaScriptなしでスクロール連動アニメーションが作れます。Chrome 115以降で対応しており、スクロール進捗に応じてアニメーションの進行度が変わる仕組みです。

Q. @keyframesでアニメーション中にプロパティを急に切り替えるには?

animation-timing-function: steps(1)を使うと、中間の補間なしに値が瞬時に切り替わります。例えばsteps(1)を指定して0%と50%で背景色を変えると、アニメーション中間で色がパッと切り替わるスプライトアニメーション的な表現が可能です。


まとめ

CSS の @keyframesanimation プロパティは非常に柔軟で、Web ページに動きを加えるのに役立ちます。今回解説した選択肢を組み合わせることで、より魅力的なアニメーションを実現できます。