Webサイトに動きを取り入れると、ユーザーの目を引くだけでなく、操作のフィードバックや情報の視認性向上にもつながります。CSSアニメーションは、JavaScriptを使わずにHTML要素に動きをつけられる手法で、パフォーマンスへの影響も少なく実装できるのが特徴です。
しかし、CSSアニメーションには「transition」と「@keyframes + animation」という2つのアプローチがあり、それぞれの特性と使い分けを理解しておかないと、無駄に複雑なコードを書いてしまう原因になります。
この記事では、CSSアニメーションの基本から実践的なテクニック、パフォーマンス上の注意点までを体系的に解説します。

transitionの基本と使い方
transitionとは
transitionは、CSSプロパティの値が変化する際に、その変化を滑らかに補間するための仕組みです。例えば、ボタンにホバーした際に背景色が瞬時に切り替わるのではなく、0.3秒かけてふんわりと変化させることができます。
transitionの基本構文は以下の通りです。
- transition-property:アニメーションさせるCSSプロパティ(例:background-color, transform, opacity)
- transition-duration:アニメーションの時間(例:0.3s, 300ms)
- transition-timing-function:動きの加減速パターン(例:ease, ease-in-out, linear)
- transition-delay:アニメーション開始までの待機時間
これらをまとめてtransition: background-color 0.3s ease;のようにショートハンドで記述するのが一般的です。
transitionの使いどころ
transitionは「状態Aから状態Bへの変化」を表現するのに適しています。具体的には以下のような場面で活用されます。
- ボタンのホバーエフェクト(背景色・サイズ・影の変化)
- ナビゲーションメニューの展開・収納
- カードの浮き上がりエフェクト(box-shadowとtransformの変化)
- フォーム入力欄のフォーカス時の枠線変化
- リンクテキストの色変化
transitionは:hoverや:focus、:activeなどの擬似クラス、またはJavaScriptによるクラスの付け外しをトリガーとして動作します。トリガーがなければアニメーションが始まらないため、ページ読み込み時に自動で動くアニメーションには向いていません。
@keyframesとanimationの基本
@keyframesとは
@keyframesは、アニメーションの各段階(キーフレーム)を定義するCSSの構文です。transitionが「開始と終了の2点間の変化」しか表現できないのに対し、@keyframesは複数の中間地点を指定して、より複雑な動きを表現できます。
キーフレームは「from(0%)」と「to(100%)」の2点で定義することも、「0%, 25%, 50%, 75%, 100%」のように細かく分割して定義することもできます。
animationプロパティの設定項目
定義した@keyframesをHTML要素に適用するには、animationプロパティを使用します。
- animation-name:@keyframesで定義した名前を指定
- animation-duration:1サイクルの所要時間
- animation-timing-function:動きの加減速パターン
- animation-delay:開始までの待機時間
- animation-iteration-count:繰り返し回数(infiniteで無限ループ)
- animation-direction:再生方向(normal, reverse, alternate)
- animation-fill-mode:アニメーション前後の状態(forwards, backwards, both)
- animation-play-state:再生・一時停止の制御(running, paused)
keyframesの使いどころ
@keyframesは以下のような場面で力を発揮します。
- ローディングアニメーション(回転、点滅、バウンスなど)
- スクロール連動のフェードインアニメーション
- 注目要素のパルス(点滅)効果
- スライダーの自動切り替え
- 背景グラデーションのアニメーション

transitionとkeyframesの使い分け判断基準
判断フローチャート
どちらを使うべきか迷った場合は、以下の判断基準を参考にしてください。
- 変化が「開始→終了」の2段階で済むか → transition
- 中間の動きを細かく制御したいか → @keyframes
- ユーザー操作(hover、clickなど)をトリガーにするか → transitionが第一候補
- ページ読み込み時に自動で再生するか → @keyframes
- アニメーションをループさせるか → @keyframes(iteration-count: infinite)
- 逆再生や交互再生が必要か → @keyframes(animation-direction)
迷ったらまずtransitionで実装してみましょう。transitionの方がコード量が少なく、メンテナンスも容易です。transitionでは表現できない動きが必要になった時点で@keyframesに切り替えるのが効率的です。
イージング(timing-function)の使い方
標準イージングの種類
イージングとは、アニメーションの速度変化のパターンを指します。同じ動きでもイージングを変えるだけで印象が大きく変わるため、適切なイージングの選択はアニメーションの品質に直結します。
- linear:一定の速度で変化。機械的な印象になるため、人為的な動きには不向き
- ease:ゆっくり始まり、速くなり、ゆっくり終わる。最も自然に見えるデフォルト値
- ease-in:ゆっくり始まり、加速して終わる。画面外への退出に適する
- ease-out:速く始まり、減速して終わる。画面内への登場に適する
- ease-in-out:ゆっくり始まり、ゆっくり終わる。要素の移動やサイズ変更に適する
cubic-bezierによるカスタムイージング
標準のイージングでは表現できない動きを作りたい場合は、cubic-bezier()関数でカスタムイージングを定義できます。cubic-bezier.comというツールを使えば、ベジェ曲線を視覚的に操作しながらイージングを作成できます。
バウンス効果(弾むような動き)やオーバーシュート(目標位置を一度通り過ぎてから戻る動き)なども、cubic-bezierで表現できます。
派手なイージングは目を引きますが、すべてのアニメーションに適用すると落ち着きのない印象になります。バウンスやオーバーシュートのような特殊なイージングは、注目させたい要素に限定して使いましょう。基本はeaseまたはease-in-outで十分です。
パフォーマンスを意識したアニメーション設計
GPUアクセラレーションを活用する
CSSアニメーションのパフォーマンスは、アニメーションさせるプロパティによって大きく異なります。
- 高パフォーマンス(GPU処理):
transform、opacity - 中パフォーマンス(レイアウト再計算なし):
color、background-color - 低パフォーマンス(レイアウト再計算あり):
width、height、margin、padding、top、left
要素の移動にはtop/leftではなくtransform: translateを、サイズ変更にはwidth/heightではなくtransform: scaleを使うのがパフォーマンス面で推奨されます。transformとopacityのアニメーションはGPUで処理されるため、メインスレッドをブロックせず滑らかに動作します。
will-changeプロパティの適切な使用
will-changeプロパティを使うと、ブラウザに「この要素はアニメーションする予定がある」と事前に伝えることができ、レンダリングの最適化が促されます。ただし、すべての要素にwill-changeを指定するのは逆効果です。実際にアニメーションする要素にのみ指定し、アニメーション完了後に解除するのが適切な使い方です。
prefers-reduced-motionへの対応
一部のユーザーは、アニメーションによって不快感やめまいを感じることがあります。OSのアクセシビリティ設定で「動きを減らす」を有効にしているユーザーに配慮するため、prefers-reduced-motionメディアクエリを使ってアニメーションを制御しましょう。
MDNのprefers-reduced-motionのドキュメントに詳しい実装方法が掲載されています。

実務で使えるCSSアニメーションのパターン
フェードイン
ページ読み込み時やスクロール時に要素をふんわりと表示するフェードインは、最も使用頻度の高いアニメーションパターンです。opacityを0から1に変化させるシンプルな実装で、translateYを組み合わせて下から浮き上がるような動きを加えると、より洗練された印象になります。
ホバーエフェクト
ボタンやカードにホバーした際のエフェクトは、ユーザーに「この要素はクリックできる」というフィードバックを与えます。背景色の変化、box-shadowの追加、transform: scaleで微妙に拡大する、transform: translateYで少し浮き上がるなどのパターンが定番です。
ローディングスピナー
データ読み込み中に表示する回転アニメーションは、@keyframesのtransform: rotateで実装します。animation-iteration-count: infiniteで無限ループさせ、ユーザーに「処理中」であることを視覚的に伝えます。
スクロールトリガーアニメーション
Intersection Observer APIとCSSアニメーションを組み合わせることで、要素が画面内に入ったタイミングでアニメーションを発動させることができます。JavaScriptでクラスを付与し、CSSでそのクラスに対してアニメーションを定義するというパターンが一般的です。
よくある質問(Q&A)
Q:CSSアニメーションとJavaScriptアニメーションはどちらを使うべきですか?
A:シンプルな動き(フェードイン、ホバーエフェクト、回転など)はCSSアニメーションが適しています。パフォーマンスが良く、コード量も少なくて済みます。一方、複雑なシーケンスアニメーション、スクロール位置に連動した動き、物理演算を伴うアニメーションなど、高度な制御が必要な場合はJavaScript(GSAP、Framer Motionなど)の方が向いています。
Q:アニメーションの適切な持続時間(duration)はどのくらいですか?
A:UIの操作フィードバック(ホバー、クリックなど)は100〜300ms、要素の表示・非表示は200〜500ms、ページ遷移やモーダルの開閉は300〜600ms程度が目安です。1秒を超えるアニメーションはユーザーに「遅い」と感じさせる原因になるため避けましょう。
Q:animation-fill-modeのforwardsとは何ですか?
A:animation-fill-mode: forwardsを指定すると、アニメーション終了後にアニメーション最後のキーフレームの状態が保持されます。例えばフェードインアニメーションでopacityを0→1に変化させた場合、forwardsを指定しないとアニメーション終了後にopacityが0に戻ってしまいます。
Q:アニメーションが「カクカク」する場合の対処法は?
A:まずアニメーションさせているプロパティを確認しましょう。width、height、margin、top、leftなどのプロパティはレイアウト再計算が発生するため、カクつきの原因になります。transformとopacityに置き換えることで改善できます。それでも解消しない場合は、will-changeプロパティを検討してください。
Q:CSSアニメーションで「ブラウザによって動きが違う」場合はどうすればいいですか?
A:ブラウザごとのレンダリングエンジンの違いにより、微妙な差異が出ることがあります。ベンダープレフィックス(-webkit-など)の付与、cubic-bezierの値の調整、アニメーションプロパティをtransformとopacityに限定するなどの対策が有効です。主要ブラウザでの動作確認は必ず実施しましょう。
まとめ
CSSアニメーションは、transitionとkeyframesの2つのアプローチを適切に使い分けることで、パフォーマンスを保ちながら効果的な動きを実装できます。transitionは「状態Aから状態Bへの変化」に、keyframesは「複雑な多段階の動き」に適しています。
パフォーマンスの観点からは、transformとopacityを中心にアニメーションを設計し、prefers-reduced-motionによるアクセシビリティ対応も忘れずに実装しましょう。過度なアニメーションはユーザー体験を損なう原因になるため、「本当に必要な動き」を見極めることが重要です。


