C
HTML/CSS/上級/Lesson 11

CSS変数・アニメーション — モダンUIに欠かせない基本語彙

45分·theory

CSS変数・アニメーション — モダンUIに欠かせない基本語彙

🎯 このlessonを読み終えたら

このlessonを読み終えると、以下の3つを自信を持ってできるようになります。

  • ✅ CSS Custom Properties(--var)でダークモードを実装する
  • ✅ transitionと@keyframesの違いを理解する
  • ✅ prefers-reduced-motionによるアクセシビリティ対応

学習目標をチェックリストとして手元に置き、すべてに答えられるようになったらlessonを閉じてください。

CSS変数(Custom Properties)— `--name`

基本的な使い方

css
:root {
    --primary: #00d066;
    --text-base: 16px;
    --radius: 8px;
}

.btn {
    background: var(--primary);
    border-radius: var(--radius);
    font-size: var(--text-base);
}

:rootグローバルスコープ。どこからでも var(--name) で参照できます。

コンポーネントスコープ

css
.card {
    --card-padding: 16px;
    padding: var(--card-padding);
}
.card.large {
    --card-padding: 32px;        /* 同じ変数、異なる値 */
}

要素ごとに変数を再定義できます。子要素が親で定義した変数をオーバーライドすることも可能。

ダークモード — 変数を一つ変えるだけ

css
:root {
    --bg: #ffffff;
    --fg: #000000;
}
[data-theme="dark"] {
    --bg: #1a1a1a;
    --fg: #e6e6e6;
}

body {
    background: var(--bg);
    color: var(--fg);
}
javascript
// JSでテーマを切り替え
document.documentElement.dataset.theme = 'dark';

色を一つ一つ変更する必要はありません — テーマ切り替えが簡単に。Tailwindの dark: バリアントはこれを自動化したものです。

prefers-color-scheme — システム設定に追従

css
@media (prefers-color-scheme: dark) {
    :root {
        --bg: #1a1a1a;
        --fg: #e6e6e6;
    }
}

ユーザーのOS設定を自動検出。手動トグルが不要なときに使います。

JSとの連携

javascript
// 読み取り
getComputedStyle(document.documentElement).getPropertyValue('--primary');

// 書き込み
document.documentElement.style.setProperty('--primary', '#ff0000');

Tailwind + CSS変数

css
@theme {
    --color-primary: #00d066;
    --radius-card: 12px;
}

Tailwind v4は完全にCSS変数ベースbg-primary が自動的に bg: var(--color-primary) になります。

transition — なめらかな状態遷移

最もシンプルな形

css
.btn {
    background: blue;
    transition: background 0.3s ease;
}
.btn:hover {
    background: red;     /* 0.3秒かけてなめらかに */
}

プロパティ / 時間 / タイミング関数 — この3つがtransitionの核心。

複数プロパティを同時に

css
.card {
    transform: translateY(0);
    box-shadow: 0 1px 2px rgba(0,0,0,0.1);
    transition: transform 0.3s, box-shadow 0.3s;
}
.card:hover {
    transform: translateY(-4px);
    box-shadow: 0 8px 16px rgba(0,0,0,0.15);
}

ホバー時にカードがわずかに浮き上がり + 影が深くなる — モダンWebの標準パターン。

タイミング関数

  • linear — 一定速度
  • ease(デフォルト)— 加速後に減速
  • ease-in — ゆっくり始まる
  • ease-out — 速く始まり、最後はなめらか(UIの標準)
  • cubic-bezier(...) — カスタム

UI遷移はほぼease-out。「速い始動 + 自然な着地」の自然さ。

transition: all の落とし穴

css
.btn {
    transition: all 0.3s;   /* ❌ 全プロパティ — パフォーマンス低下 */
}

プロパティを明示的に列挙する方が良い:

css
.btn {
    transition: background-color 0.2s, transform 0.2s;
}

アニメーション可能なプロパティとは

数値で補間できるもののみ。displayvisibilitybackground-image不可opacitytransformcolorwidthheight可能

GPUアクセラレーションが効くプロパティ: transformopacity(パフォーマンス最優秀)。width/height の変更はレイアウト再計算が発生するため遅い。

transform — translate / scale / rotate

css
.el:hover {
    transform: translateX(20px) scale(1.05) rotate(5deg);
}

マージン/パディングの変更より高速 — GPUが直接コンポジット処理。

@keyframes — 複雑なアニメーション

基本構造

css
@keyframes fadeIn {
    from { opacity: 0; transform: translateY(20px); }
    to   { opacity: 1; transform: translateY(0); }
}

.modal {
    animation: fadeIn 0.3s ease-out;
}

0% → 100%(from → to)を定義。CSSが補間を自動処理。

中間ステップが必要な場合

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

.icon { animation: bounce 1s infinite; }

ローディングスピナー — 実践的な例

css
@keyframes spin {
    to { transform: rotate(360deg); }
}

.spinner {
    width: 24px;
    height: 24px;
    border: 3px solid #eee;
    border-top-color: #00d066;
    border-radius: 50%;
    animation: spin 0.8s linear infinite;
}

あらゆるSaaSサイトで使われているスピナーがこれ。

animationプロパティの完全版

css
.el {
    animation:
        fadeIn          /* 名前 */
        0.3s            /* duration */
        ease-out        /* timing */
        0.1s            /* delay */
        forwards        /* fill-mode: 終了状態を維持 */
        infinite;       /* iteration-count */
}

一括指定。展開すると6つのプロパティ:

css
.el {
    animation-name: fadeIn;
    animation-duration: 0.3s;
    animation-timing-function: ease-out;
    animation-delay: 0.1s;
    animation-fill-mode: forwards;
    animation-iteration-count: infinite;
}

prefers-reduced-motion — アクセシビリティの必須対応

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

めまいや前庭障害のあるユーザーのためにモーションを無効化。アクセシビリティスコアに直結。

🤖 AIへのリクエスト例

  • 「このボタン、ホバー時に少し浮き上がって影を深くしてください」
  • 「CSSのローディングスピナーを作ってください。360度回転、0.8秒、無限ループ。」
  • 「prefers-reduced-motionへの対応を追加してください」
先に読むとよい概念: メディアクエリ
次のおすすめ: JavaScript 学習ガイド
CSS変数・アニメーション — モダンUIに欠かせない基本語彙 - HTML/CSS