はじめに
「ボタンにマウスを乗せたとき、色がパッと切り替わるだけで味気ない」「読み込み中のくるくる回るアイコンをCSSだけで作りたい」「同じ動きを自動で繰り返すアニメーションを付けたい」という経験はありませんか?
これらはすべて、CSSのアニメーション機能を理解すれば解決できます。
前回の記事では、要素の背景を制御するbackground関連プロパティについて解説しました。
今回は、値の変化を滑らかに見せるtransitionと、決められた動きを自動で再生・繰り返すanimationについて、仕組みの違いから書式、実務でよく使うサンプルコードまでわかりやすく解説します。
transition・animationとは?
どちらも「CSSのプロパティの値を時間の経過とともに変化させる」機能ですが、きっかけと繰り返しの扱いが異なります。
| 機能 | きっかけ | 繰り返し | 主な用途 |
|---|---|---|---|
transition | :hover などの状態変化が起きたとき | 基本は1回だけ | ホバー時の色変化、開閉時の滑らかな動き |
animation | ページ読み込みなど、指定したタイミングで自動的に | infinite で無限ループも可能 | ローディングスピナー、注意を引く点滅、自動で動く演出 |
「状態が変わったときだけ滑らかにしたい」なら transition、「ユーザー操作がなくても動かしたい・繰り返したい」なら animation と覚えると使い分けやすくなります。
transition-property(対象プロパティ)
transition-property は、どのプロパティにアニメーションを適用するかを指定します。初期値は all(すべてのプロパティが対象)です。
書式
セレクタ {
transition-property: プロパティ名;
}サンプル
.btn {
transition-property: background-color;
}all のままにしておくと便利ですが、意図しないプロパティ(width や height など)まで滑らかに変化してレイアウトがガクつくことがあるため、実務では変化させたいプロパティだけを明示的に指定することもよくあります。
transition-duration(変化にかかる時間)
transition-duration は、変化が完了するまでの時間を指定します。単位は s(秒)または ms(ミリ秒)です。初期値は 0s(アニメーションなし)です。
書式
セレクタ {
transition-duration: 時間;
}サンプル
.btn {
transition-property: background-color;
transition-duration: 0.3s;
}transition-duration を指定し忘れると初期値の 0s のままになり、transition-property だけ書いても見た目上は何も変化しません。この2つは必ずセットで指定しましょう。
transition-timing-function(変化の速度カーブ)
transition-timing-function は、時間経過に対する変化の速度カーブ(イージング)を指定します。
主な指定値
| 値 | 説明 |
|---|---|
ease | 最初ゆっくり→速く→最後ゆっくり(初期値) |
linear | 常に一定の速度 |
ease-in | ゆっくり始まり、だんだん速くなる |
ease-out | 速く始まり、だんだんゆっくりになる |
ease-in-out | ゆっくり始まり、ゆっくり終わる |
cubic-bezier(n,n,n,n) | 4つの数値で速度カーブを自由に定義 |
書式
セレクタ {
transition-timing-function: 値;
}サンプル
.btn {
transition-property: transform;
transition-duration: 0.3s;
transition-timing-function: ease-out;
}ボタンやカードが「ふわっと」浮き上がるような動きには ease-out、機械的で一定な動き(プログレスバーなど)には linear がよく使われます。
transition-delay(開始までの遅延)
transition-delay は、状態が変化してからアニメーションが始まるまでの待ち時間を指定します。初期値は 0s(遅延なし)です。
書式
セレクタ {
transition-delay: 時間;
}サンプル(少し間を置いてから表示するツールチップ)
.tooltip {
opacity: 0;
transition-property: opacity;
transition-duration: 0.2s;
transition-delay: 0.3s;
}
.wrapper:hover .tooltip {
opacity: 1;
}マウスを乗せてすぐにツールチップが出てしまうと目障りに感じることがあるため、transition-delay で一呼吸置いてから表示させる実装がよく使われます。
transition(ショートハンド)
transition は、これまで紹介した4つのプロパティをまとめて1行で指定できるショートハンドです。
書式
セレクタ {
transition: プロパティ 時間 タイミング関数 遅延時間;
}サンプル
.btn {
background-color: #0077cc;
color: #fff;
padding: 10px 20px;
border-radius: 4px;
transition: background-color 0.3s ease-out;
}
.btn:hover {
background-color: #005fa3;
}カンマ区切りで複数のプロパティにそれぞれ異なる設定を指定することもできます。
.card {
transition:
transform 0.3s ease-out,
box-shadow 0.3s ease-out;
}
.card:hover {
transform: translateY(-4px);
box-shadow: 0 8px 16px rgba(0, 0, 0, 0.15);
}「ホバー時の変化が味気ない」と感じたら、まず transition: プロパティ名 0.3s ease-out; の1行を :hover の元になるセレクタに追加してみましょう。それだけで多くの場合、動きが自然でなめらかな印象に変わります。
@keyframes(アニメーションの動きを定義する)
animation を使う前に、まず @keyframes でアニメーションの内容(どう変化するか)を定義する必要があります。0%〜100%(または from〜to)でキーフレーム(変化の節目)ごとのスタイルを指定します。
書式
@keyframes 任意の名前 {
0% {
プロパティ: 値;
}
100% {
プロパティ: 値;
}
}サンプル(フェードイン)
@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}サンプル(回転し続けるスピナー)
@keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}@keyframes はあくまで「動きの設計図」であり、これ単体では何も起こりません。実際に要素へ適用するには、次の animation 関連プロパティと組み合わせます。
animation-name / animation-duration(適用する動きと時間)
animation-name で使用する @keyframes の名前を、animation-duration で1回分の再生時間を指定します。
書式
セレクタ {
animation-name: keyframes名;
animation-duration: 時間;
}サンプル
.spinner {
width: 32px;
height: 32px;
border: 4px solid #eee;
border-top-color: #0077cc;
border-radius: 50%;
animation-name: spin;
animation-duration: 0.8s;
}transition-duration と同様、animation-duration を指定し忘れると初期値の 0s のままアニメーションが再生されません。
animation-timing-function / animation-iteration-count(速度カーブと再生回数)
animation-timing-function は transition と同じ ease linear などの値が使えます。animation-iteration-count は再生回数を指定し、数値のほか infinite(無限ループ)が指定できます。
書式
セレクタ {
animation-timing-function: 値;
animation-iteration-count: 回数;
}サンプル(スピナーを無限に回し続ける)
.spinner {
animation-name: spin;
animation-duration: 0.8s;
animation-timing-function: linear;
animation-iteration-count: infinite;
}回転や点滅のようにずっと同じ動きを繰り返す演出では、animation-timing-function: linear; と animation-iteration-count: infinite; の組み合わせが定番です。
animation-direction(再生方向)
animation-direction は、アニメーションを毎回同じ向きで再生するか、往復させるかを指定します。
主な指定値
| 値 | 説明 |
|---|---|
normal | 毎回 0% → 100% の順で再生(初期値) |
reverse | 毎回 100% → 0% の順で再生 |
alternate | 0%→100%、次は100%→0% と交互に再生(往復) |
alternate-reverse | alternate の逆順から開始 |
書式
セレクタ {
animation-direction: 値;
}サンプル(ふわふわ上下に揺れるアイコン)
@keyframes float {
0% {
transform: translateY(0);
}
100% {
transform: translateY(-10px);
}
}
.icon {
animation-name: float;
animation-duration: 1s;
animation-timing-function: ease-in-out;
animation-iteration-count: infinite;
animation-direction: alternate;
}alternate を指定することで、@keyframes 側は「上に10px動く」動きしか定義していなくても、行き(上へ)と帰り(下へ)を自動的に往復してくれます。
animation-fill-mode(再生前後のスタイル維持)
animation-fill-mode は、アニメーションの再生前・再生後にキーフレームのスタイルを適用し続けるかを指定します。指定しないと、再生が終わった瞬間に元のスタイルへ戻ってしまいます。
主な指定値
| 値 | 説明 |
|---|---|
none | 再生前後とも適用しない(初期値) |
forwards | 再生後、最後(100%)のスタイルを維持する |
backwards | 再生前から、最初(0%)のスタイルを適用しておく |
both | forwards と backwards の両方を適用する |
サンプル(1回だけ再生してフェードインした状態を維持)
@keyframes fadeIn {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.card {
animation-name: fadeIn;
animation-duration: 0.6s;
animation-timing-function: ease-out;
animation-fill-mode: forwards;
}animation-fill-mode: forwards; を忘れると、フェードインが終わった瞬間に要素が元の(opacity: 0 の)状態へ戻ってしまい、「一瞬だけ表示されて消えた」ように見えるトラブルになりがちです。再生後の状態を保ちたい場合は必ず指定しましょう。
animation(ショートハンド)
animation は、これまで紹介したプロパティをまとめて1行で指定できるショートハンドです。
書式
セレクタ {
animation: 名前 時間 タイミング関数 遅延時間 回数 方向 fill-mode;
}サンプル
.spinner {
animation: spin 0.8s linear infinite;
}
.card {
animation: fadeIn 0.6s ease-out forwards;
}transition と同様、値の順序はある程度自由ですが、時間を表す値が2つある場合は最初がduration・2つ目がdelayとして解釈される点に注意してください。
実務サンプル(読み込み中に表示するローディングスピナー)
@keyframes と animation を組み合わせた、実務でそのまま使えるサンプルです。
HTML
<div class="loading">
<div class="spinner"></div>
<p>読み込み中です…</p>
</div>CSS
@keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
.loading {
display: flex;
align-items: center;
gap: 12px;
}
.spinner {
width: 24px;
height: 24px;
border: 3px solid #eee;
border-top-color: #0077cc;
border-radius: 50%;
animation: spin 0.8s linear infinite;
}円形の枠のうち上側だけ色を変えた要素を rotate() で回し続けることで、一般的な「くるくる回るローディングアイコン」を画像を使わずCSSだけで再現できます。
よくある質問・トラブル対処
Q. transitionを指定したのに変化がカクカクする
→ アニメーション対象のプロパティによっては、ブラウザの描画負荷が高くなり滑らかに動かないことがあります。transform や opacity はブラウザが高速に処理できるプロパティのため、可能な限りこの2つで動きを表現するのがおすすめです。
Q. animationを指定したのに、再生後に元の見た目へ戻ってしまう
→ animation-fill-mode の初期値は none のため、再生後は自動的に元のスタイルへ戻ります。最後のキーフレームの見た目を維持したい場合は animation-fill-mode: forwards; を指定してください。
Q. transitionとanimation、どちらを使えばいいかわからない
→ 「マウスを乗せた・クリックした」などユーザー操作をきっかけに1回だけ変化させたい場合は transition、ページ表示時や読み込み中などきっかけなしで自動的に、繰り返し動かしたい場合は animation を選ぶとよいでしょう。
Q. display: none; の要素にtransitionが効かない
→ display プロパティはアニメーション対象にできません。表示・非表示を滑らかに切り替えたい場合は、display の代わりに opacity と visibility、あるいは max-height などを組み合わせて実装します。
おわりに(まとめ)
transition・animationを使いこなせると、状態変化を滑らかに見せたり、自動で繰り返す動きを付けたりと、Webページの印象を大きく改善できます。
- ✅
transitionは状態変化(:hoverなど)をきっかけに1回だけ滑らかに変化させる - ✅
animationはきっかけなしで自動再生でき、infiniteで無限ループもできる - ✅
animationを使うには、先に@keyframesで動きを定義しておく必要がある - ✅
animation-fill-mode: forwards;を付け忘れると再生後に元の見た目へ戻ってしまう - ✅ アニメーション対象は
transformやopacityにすると滑らかに動きやすい
まず transition: プロパティ名 0.3s ease-out; の1行から試してみましょう。
ホバー時の色変化やカードの浮き上がりなど、実務でよくある場面の大半はこの1行だけで自然な動きに変わります。画面いっぱいに崩れず表示する」場面の大半に対応できます。4つだけでも、ボタンの装飾やリストの縞模様、アイコン表示など、実務でよく使う場面の大半に対応できます。
次回は、CSSのリスト関連プロパティについて解説予定です。
この記事が、少しでも誰かのお役に立てれば幸いです。
関連記事
- 【CSS】背景(background)関連プロパティの使い方を基本から解説
- 【CSS】疑似クラス・疑似要素の使い方を基本から解説
- 【CSS】flexboxレイアウトの使い方を基本から解説
- 【CSS】フォント関連プロパティについて基本解説
- Webページに関する基礎的な勉強を始めます
当サイトの記事で使用したVBAなどのサンプルをDLできます
この記事のサンプルはありません!
ダウンロードページへは下のカードをクリックすればジャンプできます。
よろしければご利用ください!

