Back

使用 CSS cross-fade() 混合图像

使用 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-imagemask-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))
    );
  }
}

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..

OpenReplay