CreaTools LogoCreaTools
Gradient Maker

CSSグラデーションアニメーション|パフォーマンスを落とさない3つの手法

2025-11-14

:::note ※アニメーションを入れる前に読む「注意喚起」記事です :::

結論(30秒で分かる要点)

  • 前提background-image のグラデーションは transition / @keyframes で直接変化させられない
  • 推奨手法background-position の移動(全ブラウザ対応・軽量)
  • 色を直接変えたい@property(Chrome/Edge のみ、Safari未対応)

💡 アニメーション前のベースグラデーションを作る → Gradient Maker


よくある失敗(実務で踏む地雷)

❌ 失敗1:グラデーションを直接 transition しようとする

/* ❌ これは動かない */
.gradient {
  background: linear-gradient(90deg, #667eea, #764ba2);
  transition: background 0.3s;
}

.gradient:hover {
  background: linear-gradient(90deg, #f093fb, #f5576c);
}

background-image は補間できないため、transition が効かない。切り替わるだけでアニメーションしない。

❌ 失敗2:will-change を常時指定する

/* ❌ 常時指定はメモリを浪費 */
.gradient {
  will-change: background-position;
}

/* ✅ 必要なときだけ(ホバー時など) */
.gradient:hover {
  will-change: background-position;
}

will-change は「これからアニメーションする」というヒント。常時ONはリソースの無駄。

❌ 失敗3:大きな要素で background-size を巨大にする

/* ❌ 200% でも重いのに 400% は危険 */
.hero {
  width: 100vw;
  height: 100vh;
  background-size: 400% 400%;
  animation: gradient-shift 3s ease infinite;
}

フルスクリーン要素で background-size: 400% は GPU メモリを大量消費。60fps 出ないことがある。

❌ 失敗4:@property を Safari で使う

/* ❌ Safari で動かない(2025年現在) */
@property --gradient-start {
  syntax: '<color>';
  initial-value: #667eea;
  inherits: false;
}

@property は Chrome/Edge のみ対応。Safari ではフォールバック必須。


手法1:background-position(推奨)

グラデーションを大きく作り、位置をずらしてアニメーション。全ブラウザ対応・最も軽量

.gradient-animate {
  background: linear-gradient(90deg, #667eea, #764ba2, #667eea);
  background-size: 200% 100%;
  animation: gradient-shift 3s ease infinite;
}

@keyframes gradient-shift {
  0% { background-position: 0% 50%; }
  50% { background-position: 100% 50%; }
  100% { background-position: 0% 50%; }
}

ポイント

  • グラデーションの最後に最初の色を追加(ループを滑らかに)
  • background-size: 200% 100% で横に2倍
  • position の移動でスクロール効果

Generatorでベースのグラデーションを作成


手法2:疑似要素でフェード

2つのグラデーションを重ねて opacity で切り替え。色の変化を表現可能

.gradient-fade {
  position: relative;
  background: linear-gradient(90deg, #667eea, #764ba2);
}

.gradient-fade::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg, #f093fb, #f5576c);
  opacity: 0;
  transition: opacity 0.5s;
  pointer-events: none;
}

.gradient-fade:hover::after {
  opacity: 1;
}

メリット:異なる色のグラデーション間を滑らかに遷移 デメリット:DOM要素が増える、z-index の管理が必要


手法3:CSS Houdini @property

@property で CSS 変数を型付きで登録し、グラデーションの色を直接アニメーション。

@property --gradient-start {
  syntax: '<color>';
  initial-value: #667eea;
  inherits: false;
}

@property --gradient-end {
  syntax: '<color>';
  initial-value: #764ba2;
  inherits: false;
}

.gradient-houdini {
  background: linear-gradient(90deg, var(--gradient-start), var(--gradient-end));
  transition: --gradient-start 0.5s, --gradient-end 0.5s;
}

.gradient-houdini:hover {
  --gradient-start: #f093fb;
  --gradient-end: #f5576c;
}

⚠️ 重要:Safari 未対応(2025年現在)

フォールバック付き実装:

/* フォールバック:疑似要素方式 */
.gradient-houdini {
  position: relative;
  background: linear-gradient(90deg, #667eea, #764ba2);
}

.gradient-houdini::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg, #f093fb, #f5576c);
  opacity: 0;
  transition: opacity 0.5s;
  pointer-events: none;
}

.gradient-houdini:hover::after {
  opacity: 1;
}

/* @property 対応ブラウザ用 */
@supports (background: paint(something)) {
  @property --gradient-start {
    syntax: '<color>';
    initial-value: #667eea;
    inherits: false;
  }
  
  @property --gradient-end {
    syntax: '<color>';
    initial-value: #764ba2;
    inherits: false;
  }
  
  .gradient-houdini {
    background: linear-gradient(90deg, var(--gradient-start), var(--gradient-end));
    transition: --gradient-start 0.5s, --gradient-end 0.5s;
  }
  
  .gradient-houdini::after {
    display: none;
  }
  
  .gradient-houdini:hover {
    --gradient-start: #f093fb;
    --gradient-end: #f5576c;
  }
}

パフォーマンス比較

手法パフォーマンスブラウザ対応色の変化推奨度
background-position◎ 良好✅ 全ブラウザ×★★★
疑似要素フェード○ 良好✅ 全ブラウザ★★☆
@property△ やや重い⚠️ Chrome/Edge のみ★☆☆

パフォーマンスの注意点

  1. 大きな要素でのアニメーション

    • フルスクリーン要素は GPU 負荷が高い
    • background-size は 200% 程度に抑える
  2. スクロール中のアニメーション

    • スクロールと同時にアニメーションすると jank が発生しやすい
    • will-change: background-position を検討
  3. 複数要素の同時アニメーション

    • 同時に多数の要素をアニメーションすると重くなる
    • animation-delay でずらすか、表示中の要素のみアニメーション

具体例:このUIならこの設定

ケース1:ボタンのホバーエフェクト(推奨)

.button {
  background: linear-gradient(90deg, #667eea, #764ba2, #667eea);
  background-size: 200% auto;
  transition: background-position 0.3s;
}

.button:hover {
  background-position: 100% center;
}

ケース2:ローディングインジケーター

.loading-bar {
  height: 4px;
  background: linear-gradient(90deg, #667eea, #764ba2, #667eea);
  background-size: 200% 100%;
  animation: loading 1.5s ease infinite;
}

@keyframes loading {
  0% { background-position: 100% 0; }
  100% { background-position: -100% 0; }
}

ケース3:ヒーローセクション(控えめに)

.hero {
  background: linear-gradient(135deg, #667eea, #764ba2, #667eea);
  background-size: 200% 200%;
  animation: hero-gradient 15s ease infinite; /* 遅めに */
}

@keyframes hero-gradient {
  0%, 100% { background-position: 0% 50%; }
  50% { background-position: 100% 50%; }
}

ヒーローでは遅いアニメーション(10秒以上)を推奨。速いと目障り。


ブラウザ対応

ブラウザbackground-position疑似要素@property
Chrome
Safari
Firefox
Edge

結論:Safari 対応が必要なら background-position か疑似要素を使う。


まとめ:判断基準

条件推奨アプローチ
全ブラウザ対応が必要background-position(推奨)
色を滑らかに変化させたい疑似要素フェード
Safari 不要 + 最新実装したい@property
パフォーマンス重視background-position + 遅めのアニメーション
ベースのグラデーション作成Gradient Maker

この記事で解決しない場合