使用 CSS cross-fade() 混合图像
在 CSS 中合成两张图像,以前需要使用 position: absolute 堆叠元素并分别调整每个元素的 opacity 值,还需要额外的标记或 JavaScript。而 cross-fade() 函数完全消除了这些开销,它可以直接在样式表中生成单个混合的 <image> 值。
核心要点
cross-fade()是一个 CSS 图像函数,可以将两个或多个图像按指定的不透明度权重合成为单个<image>值,可用于任何 CSS 期望图像的地方。- 百分比权重控制每个输入在混合中的不透明度。省略的百分比会从 100% 的余数中自动分配。
- 浏览器支持不均衡:Chromium 和 Safari 支持旧版的
-webkit-cross-fade()语法,而 Firefox 截至 2026 年初仍未实现任何版本。 - 使用
@supports块将带前缀的旧版语法和规范语法分层应用在可靠的后备图像之上,以实现渐进增强。
CSS cross-fade() 的实际作用
cross-fade() 是一个生成图像的 CSS 函数,定义在 CSS Images Level 4 规范中。它接受两个或多个图像——位图文件、渐变、SVG 或纯色——按指定权重混合它们,并输出单个 <image> 值。因为输出就是图像类型,所以你可以在任何 CSS 期望图像的地方使用它:background-image、mask-image 或伪元素的 content 属性。
这个区别很重要。与分层两个 background-image 值并应用 background-blend-mode 不同,cross-fade() 在渲染之前就将输入合成为一个结果。无需额外的 DOM 节点,没有堆叠上下文的副作用。
百分比权重的工作原理
每个参数接受一个可选的百分比,用于控制该输入在最终混合中的不透明度。有几条规则控制计算:
- **未声明百分比:**输入平均分配。两张图像各得 50%;三张图像各得约 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%)
/* 三个输入,一个未指定 — 获得余数(30%) */
cross-fade(url(a.jpg) 40%, url(b.jpg) 30%, url(c.jpg))
规范语法 vs. WebKit 实现
这里情况变得不均衡。CSS Images Level 4 规范定义的 cross-fade() 支持多个输入,每个输入都有独立的百分比。而较旧的 WebKit 实现——仍然是基于 Chromium 的浏览器和 Safari 实际渲染的版本——只接受两个参数,并且只有一个百分比应用于第一张图像。
**截至 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() vs. 相关 CSS 工具
| 需求 | 使用 |
|---|---|
| 按不透明度权重混合两张图像 | cross-fade() |
| 混合颜色值 | color-mix() |
| 在背景层之间应用混合模式 | background-blend-mode |
| 将元素与其后面的内容混合 | mix-blend-mode |
可访问性说明
背景图像——包括由 cross-fade() 生成的图像——对屏幕阅读器不可见。如果混合图像传达了对页面至关重要的含义,请在 HTML 中表示该内容,并确保任何文本与混合背景之间有足够的颜色对比度。
总结
cross-fade() 是一个专注的工具:它在样式表级别合成图像,保持标记整洁,并且今天在 Chromium 和 Safari 中使用 -webkit- 前缀就能工作。先编写后备方案,在其上分层 @supports 块,你就有了一个渐进增强的 CSS 图像混合解决方案,在 Firefox 中会优雅降级,直到支持到来。
常见问题
在实践中,这在各浏览器中并不可靠。如果你需要两张图像之间的平滑淡入淡出动画,请将它们作为单独的元素或背景层堆叠,并改为动画化它们的不透明度值。
是的。cross-fade() 函数接受任何有效的 CSS 图像类型作为输入,包括 linear-gradient()、radial-gradient()、conic-gradient() 和 SVG 引用。这使得它可以在单个声明中将照片与渐变叠加混合。
生成的图像尺寸计算为输入图像尺寸的加权平均值。在实现旧版 WebKit 语法的浏览器中,渲染行为可能略有不同。
没有广泛采用的 polyfill。Firefox 最可靠的解决方法是使用多个 background-image 层结合 background-blend-mode,或者使用绝对定位堆叠元素并单独控制它们的不透明度。
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..