CSSのcross-fade()を使った画像のブレンド
CSSで2つの画像を合成する際、これまでは追加のマークアップやJavaScriptを使わない場合、position: absoluteで要素を重ね、それぞれにopacity値を設定するという方法が一般的でした。cross-fade()関数を使えば、そうした手間を完全に省き、スタイルシート内で直接ブレンドされた単一の<image>値を生成できます。
重要なポイント
cross-fade()は、2つ以上の画像を指定した不透明度の重みで合成し、単一の<image>値を生成するCSS画像関数です。CSSが画像を期待する場所であればどこでも使用できます。- パーセンテージの重みによって、ブレンド内の各入力の不透明度が制御されます。パーセンテージが省略された場合、100%の残りから自動的に均等配分されます。
- ブラウザサポートは不均一です。ChromiumとSafariはレガシーの
-webkit-cross-fade()構文をサポートしていますが、Firefoxは2026年初頭時点で実装がありません。 @supportsブロックを使用して、プレフィックス付きのレガシー構文と仕様構文を、確実なフォールバック画像の上に重ねることで、プログレッシブエンハンスメントを実現します。
CSSのcross-fade()が実際に行うこと
cross-fade()は、CSS Images Level 4仕様で定義されている画像生成CSS関数です。ビットマップファイル、グラデーション、SVG、単色など、2つ以上の画像を受け取り、指定された重みでブレンドして、単一の<image>値を出力します。出力が画像タイプであるため、CSSが画像を期待する場所であればどこでも使用できます。background-image、mask-image、または疑似要素のcontentプロパティなどです。
この区別は重要です。2つのbackground-image値を重ねてbackground-blend-modeを適用する方法とは異なり、cross-fade()はレンダリング前に入力を1つの結果に合成します。追加のDOMノードも、スタッキングコンテキストの副作用もありません。
パーセンテージの重みの仕組み
各引数には、最終的なブレンドにおいてその入力がどの程度不透明であるかを制御するオプションのパーセンテージを指定できます。計算を支配するいくつかのルールがあります。
- パーセンテージが宣言されていない場合: 入力は均等に共有されます。2つの画像はそれぞれ50%、3つの画像はそれぞれ約33.3%になります。
- 一部のパーセンテージが省略されている場合: ブラウザは宣言された値を合計し、100%から減算し、残りを未指定の入力間で均等に配分します。
- 合計が100%を超える場合: 残りが負になるため、未指定の入力は0%(完全に透明)として扱われます。
- 合計が100%未満の場合: 不足分は、ギャップを埋める不可視の透明レイヤーとして機能します。
/* 均等ブレンド — パーセンテージ不要 */
cross-fade(url(a.jpg), url(b.jpg)) /* 50% / 50% */
/* 重み付きブレンド */
cross-fade(url(a.jpg) 70%, url(b.jpg) 30%)
/* 3つの入力、1つ未指定 — 残り(30%)を取得 */
cross-fade(url(a.jpg) 40%, url(b.jpg) 30%, url(c.jpg))
仕様構文とWebKit実装の違い
ここで状況が不均一になります。CSS Images Level 4仕様では、複数の入力と入力ごとの独立したパーセンテージをサポートするcross-fade()が定義されています。古いWebKit実装(ChromiumベースのブラウザとSafariが実際にレンダリングするもの)は、正確に2つの引数と最初の画像にのみ適用される1つのパーセンテージを受け入れます。
2026年初頭時点: Chromiumベースのブラウザはプレフィックス付きの-webkit-レガシー構文をサポートしています。Safariはプレフィックス付きとプレフィックスなしの両方のレガシー構文をサポートしています。Firefoxはcross-fade()を全く実装していません。現在のステータスはWebStatusで確認できます。
@supportsを使用して、両方の構文を確実なフォールバックと共に重ねます。
/* ベースフォールバック — すべてのブラウザ */
.hero {
background-image: url('fallback.jpg');
}
/* レガシーWebKit構文 — Chrome、Safari */
@supports (background-image: -webkit-cross-fade(url(a), url(b), 50%)) {
.hero {
background-image: -webkit-cross-fade(
url('photo.jpg'),
linear-gradient(to bottom, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.6)),
60%
);
}
}
/* 仕様構文 — 将来対応 */
@supports (background-image: cross-fade(url(a) 50%, url(b))) {
.hero {
background-image: cross-fade(
url('photo.jpg') 60%,
linear-gradient(to bottom, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.6))
);
}
}
Discover how at OpenReplay.com.
CSS画像ブレンドの実用的なユースケース
cross-fade()を使ったCSS画像合成は、マークアップを追加せずに視覚効果を得たい場合に最も有用です。
- 画像の色調整: 写真を単色またはグラデーションとブレンドして、CSS内で直接ブランドカラーを適用します。
- グラデーションオーバーレイ: 疑似要素を使わずに、ヒーロー画像の上に暗くするグラデーションを重ねてテキストの可読性を向上させます。
- 軽量なテクスチャ効果: SVGテクスチャをフラットカラーの背景とブレンドします。
向いていない用途:タイマーで画像間をアニメーション遷移させること。その場合、重ねた要素に対するopacityキーフレームアニメーションの方が、より互換性があり制御しやすいアプローチです。
cross-fade()と関連するCSSツールの比較
| 必要な処理 | 使用するもの |
|---|---|
| 不透明度の重みで2つの画像をブレンド | cross-fade() |
| 色の値をブレンド | color-mix() |
| 背景レイヤー間にブレンドモードを適用 | background-blend-mode |
| 要素を背後のものとブレンド | mix-blend-mode |
アクセシビリティに関する注意
cross-fade()で生成されたものを含む背景画像は、スクリーンリーダーには認識されません。ブレンドされた画像がページにとって重要な意味を持つ場合は、代わりにHTML内でそのコンテンツを表現し、テキストとブレンドされた背景の間に十分な色のコントラストがあることを確認してください。
まとめ
cross-fade()は焦点を絞ったツールです。スタイルシートレベルで画像を合成し、マークアップをクリーンに保ち、-webkit-プレフィックスを使えば今日ChromiumとSafariで動作します。まずフォールバックを記述し、その上に@supportsブロックを重ねることで、Firefoxでサポートが実装されるまで適切に劣化する、プログレッシブエンハンスメントされたCSS画像ブレンドソリューションが得られます。
よくある質問
実際には、これはブラウザ間で信頼性がありません。2つの画像間でスムーズなクロスフェードアニメーションが必要な場合は、別々の要素または背景レイヤーとして重ね、代わりにそれらのopacity値をアニメーション化してください。
はい。cross-fade()関数は、linear-gradient()、radial-gradient()、conic-gradient()、SVG参照を含む、有効なCSS画像タイプを入力として受け入れます。これにより、単一の宣言で写真とグラデーションオーバーレイをブレンドするのに便利です。
結果の画像サイズは、入力画像のサイズの加重平均として計算されます。古いWebKit構文を実装しているブラウザでは、レンダリング動作がわずかに異なる場合があります。
広く採用されているポリフィルはありません。Firefoxで最も信頼できる回避策は、background-blend-modeと組み合わせた複数のbackground-imageレイヤーを使用するか、absolute positioningで要素を重ねて個別にopacityを制御することです。
Truly understand users experience
See every user interaction, feel every frustration and track all hesitations with OpenReplay — the open-source digital experience platform. It can be self-hosted in minutes, giving you complete control over your customer data. . Check our GitHub repo and join the thousands of developers in our community..