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 の移動でスクロール効果
手法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 のみ | ◎ | ★☆☆ |
パフォーマンスの注意点
-
大きな要素でのアニメーション
- フルスクリーン要素は GPU 負荷が高い
background-sizeは 200% 程度に抑える
-
スクロール中のアニメーション
- スクロールと同時にアニメーションすると jank が発生しやすい
will-change: background-positionを検討
-
複数要素の同時アニメーション
- 同時に多数の要素をアニメーションすると重くなる
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 |
この記事で解決しない場合
- アニメーションなしで角度や構文を理解したい → linear-gradientの角度を正しく理解する(動かす前に静的な理解を)
- アニメーションするグラデーション文字を作りたい → CSSでグラデーション文字を作る(本記事のbackground-position手法と組み合わせる)