CSS REFERENCE

インタラクティブ

transition 要素

ー 状態変化をなめらかにつなぐ、UIアニメーションの入り口

POINT !

transition 要素のポイント!

  • transition は「AからBへの変化」をなめらかにするプロパティ。:hover・:focus などのトリガーがあって初めて動く。自発的にループするアニメーションは animation を使う。
  • transition-property には変化させたいプロパティ名を指定する。all は便利だが、意図しないプロパティまでアニメーションされパフォーマンスが落ちる可能性があるため、具体名(background-color, transform など)を明示するのが実務の慣習。
  • GPU アクセラレーションが効くのは transform と opacity のみ。color や width のアニメーションはレイアウトの再計算(reflow)を引き起こすため、滑らかさを求めるなら transform で表現し直す設計が重要。
  • 複数プロパティをそれぞれ違うタイミングで動かしたいときは、カンマ区切りで複数記述できる。例:transition: transform 0.3s ease, opacity 0.2s ease-out。

概要

transition は、CSS プロパティの値が変化する際に「即座にパチっと切り替わる」のではなく、「なめらかに補間しながら変化する」ようにするためのプロパティです。

Web の UX において「動き」は単なる装飾ではなく、ユーザーの認知を助ける重要な手がかりです。ボタンがホバーで色を変える、モーダルがフェードインするなど、transition が適切に使われたインターフェースは「生きているUI」として直感的に操作できます。

transition は4つのサブプロパティの短縮形です。
・transition-property:アニメーションするプロパティ名
・transition-duration:変化にかかる時間(必須)
・transition-timing-function:速度変化の曲線(イージング)
・transition-delay:変化が始まるまでの待機時間

animation との最大の違いは「トリガーの存在」です。transition はあくまで「状態Aから状態Bへの橋渡し」であり、CSS のある値が変化するという外部のトリガー(クラスの付け替えや :hover など)なしには発動しません。

このシンプルさが、UI の微細なインタラクション実装における最強の武器になります。

具体的な役割

ボタン・リンク・カードのホバー演出、ナビゲーションメニューの開閉、フォームのフォーカス時のボーダー変化、モーダルやドロワーの表示/非表示など、ユーザー操作に対するフィードバックとして使う。

アクセシビリティ

♿ transition はユーザーに動きを提供しますが、前庭障害などでアニメーションが苦手な方への配慮が必要です。

必ず @media (prefers-reduced-motion: reduce) と組み合わせ、動きを無効化または最小化するフォールバックを用意してください。

また、transition-duration が極端に長い(1秒以上)場合、フォーカスの移動が遅れてキーボードユーザーが混乱することがあります。インタラクションの transition は 200〜400ms 程度が適切です。

フォーカスインジケーター(:focus-visible のアウトラインなど)にも transition を設定する場合は、キーボード操作時に視認できるタイミングを損なわないよう注意しましょう。

セットで使うプロパティ

📦 transition は対象要素に直接記述し、その要素の「どのプロパティをどのように変化させるか」を定義します。

【アニメーション可能なプロパティ】
数値・色・座標など、2点間を補間できる値を持つプロパティが対象です。
display: none → block のような離散的な変化(補間不可能)はアニメーションされません(display は Chrome 117以降で補間が一部サポートされ始めています)。

【セットで使うプロパティ】
・transform:translateX / scale / rotate などの視覚変換(GPU加速あり)
・opacity:表示/非表示のフェード(GPU加速あり)
・will-change: transform:ブラウザへの事前ヒント(多用禁止)

技術の変遷:昔の常識 vs 今の常識

TRADITION (昔)
JavaScript で setInterval を使い、スタイルを1フレームごとに書き換えてアニメーションを実装していた。jQueryの .animate() もその延長。ブラウザの描画タイミングと合わず、カクつきやパフォーマンス問題が常につきまとった。
MODERN (今)
CSS transition + transform / opacity の組み合わせで GPU アクセラレーションの恩恵を受けながらアニメーション。JavaScript が必要なら requestAnimationFrame や Web Animations API を使う。prefers-reduced-motion による配慮もセットで実装するのが現代の標準。

関連する値

値 / 関連 説明
transition-property アニメーション対象のCSSプロパティ名。all(非推奨)または具体的なプロパティ名(transform, opacity など)を指定
transition-duration 変化にかかる時間。s(秒)または ms(ミリ秒)で指定。必須項目で、省略すると 0s になり変化が見えない
transition-timing-function 変化の速度曲線。ease(デフォルト)/ linear / ease-in / ease-out / ease-in-out / cubic-bezier() / steps() が使用可能
transition-delay 変化が始まるまでの待機時間。負の値を指定するとアニメーションを途中から開始できる
初期値 all 0s ease 0s(すべてのプロパティ、即時変化、ease、遅延なし)
継承 なし
GPU加速が効く値 transform と opacity のみ。他プロパティのアニメーションはCPUレンダリングとなりパフォーマンスに注意

利用例

ホバーで浮き上がるカード

transform と box-shadow を transition でアニメーション。GPU加速が効く transform を使いperfomanceに配慮した実装。

HTML Structure
<div style="display:flex;gap:20px;padding:40px;background:#f1f5f9;border-radius:12px;justify-content:center">
  <div class="card" style="background:white;border-radius:12px;padding:28px 24px;width:160px;text-align:center;cursor:pointer;box-shadow:0 2px 8px rgba(0,0,0,0.08)">
    <div style="font-size:32px;margin-bottom:10px">✨</div>
    <div style="font-weight:700;font-size:14px">ホバーしてね</div>
  </div>
  <div class="card" style="background:white;border-radius:12px;padding:28px 24px;width:160px;text-align:center;cursor:pointer;box-shadow:0 2px 8px rgba(0,0,0,0.08)">
    <div style="font-size:32px;margin-bottom:10px">🚀</div>
    <div style="font-weight:700;font-size:14px">こっちも</div>
  </div>
</div>
CSS Style
.card {
  transition:
    transform 0.25s ease-out,
    box-shadow 0.25s ease-out;
}

.card:hover {
  transform: translateY(-6px);
  box-shadow: 0 16px 40px rgba(0, 0, 0, 0.15);
}

/* 動きを減らす設定への配慮 */
@media (prefers-reduced-motion: reduce) {
  .card { transition: none; }
}

複数プロパティを別々のタイミングで動かす

カンマ区切りで複数の transition を定義。背景色は0.4s、文字色は即座に変化させる例。

HTML Structure
<div style="display:flex;align-items:center;justify-content:center;padding:48px;background:#f8fafc;border-radius:12px">
  <button class="btn" style="background:#1a56db;color:white;padding:14px 32px;border-radius:8px;border:none;cursor:pointer;font-size:16px;font-weight:700;font-family:sans-serif;transition:background-color 0.4s ease,transform 0.15s ease,box-shadow 0.4s ease" onmouseover="this.style.backgroundColor='#1240a8';this.style.transform='scale(1.03)';this.style.boxShadow='0 8px 24px rgba(26,86,219,0.4)'" onmouseout="this.style.backgroundColor='#1a56db';this.style.transform='scale(1)';this.style.boxShadow='none'">クリックしてみて</button>
</div>
CSS Style
.btn {
  background: #1a56db;
  color: white;
  padding: 12px 28px;
  border-radius: 8px;
  border: none;
  cursor: pointer;

  /* 複数プロパティに個別設定 */
  transition:
    background-color 0.4s ease,
    transform 0.15s ease,
    box-shadow 0.4s ease;
}

.btn:hover {
  background-color: #1240a8;
  transform: scale(1.03);
  box-shadow: 0 8px 24px rgba(26,86,219,0.4);
}

.btn:active {
  transform: scale(0.97);
  transition-duration: 0.05s; /* クリック時は素早く */
}

よくある誤用・注意点

transition: all を使うと意図しないプロパティ(height・padding・borderなど)もアニメーション対象になり、パフォーマンスが低下したり、予期しない視覚的バグが起きる。また、display や visibility の切り替えに transition を期待する誤りも多い。

HTML Structure
CSS (Incorrect)
/* ❌ 悪い例:all はパフォーマンスリスクあり */
.box {
  transition: all 0.3s ease;
}

/* ❌ 悪い例:display は補間できないため transition は無意味 */
.modal {
  display: none;
  transition: display 0.3s ease; /* 効果なし */
}

/* ✅ 良い例:プロパティを明示し、表示切り替えは opacity + visibility で */
.modal {
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.3s ease, visibility 0s 0.3s;
}
.modal.is-open {
  opacity: 1;
  visibility: visible;
  transition: opacity 0.3s ease, visibility 0s;
}