直接给加mix-blend-mode做不出双色调,因为该属性需与背后内容混合,而单张图片默认无有效 backdrop(如纯白/透明背景或被层叠上下文隔离),且双色调需两个伪元素分别以multiply和screen叠加于带基色的容器上才能实现。

为什么直接给 <img> 加 mix-blend-mode 做不出双色调?
因为 mix-blend-mode 不是“给图片上色”,而是让当前元素和它**背后的内容**(backdrop)混合。单张 <img> 默认浮在最上层,背后若只有白色或透明父容器,就无内容可混——等于没发生任何事。
常见翻车点包括:
- 父容器没设背景色/渐变,或背景是纯白(
background: #fff)→ 混合后几乎看不出变化 - 父容器用了
isolation: isolate、transform、opacity: 0.99等触发新层叠上下文 → 隔断混合链路 - 误把图片当
background-image使用 →mix-blend-mode对 background 无效,得换background-blend-mode
双色调本质是两层叠加:阴影层 + 高光层
不是靠一个模式调整整张图,而是用两个绝对定位的伪元素分别覆盖图片,各自承担明暗区域染色任务:
- 阴影层用
mix-blend-mode: multiply:深色区域吃色明显,浅色基本不变 - 高光层用
mix-blend-mode: screen:亮部提亮并染色,暗部影响极小 - 两层都需设
position: absolute; top: 0; left: 0; width: 100%; height: 100%; z-index: 1 - 颜色必须带 alpha(如
rgba(255, 0, 100, 0.6)),不透明会糊掉纹理细节
用 ::before 和 ::after 实现双色调的最小可行代码
HTML 保持干净:<div class="dual-tone"><img src="photo.jpg" alt=""></div>
CSS 关键部分:
.dual-tone {
position: relative;
/* 必须有非白底,否则 multiply/screen 都失效 */
background: linear-gradient(to bottom, #1a1a2e, #16213e);
}
.dual-tone img {
display: block;
width: 100%;
height: auto;
}
.dual-tone::before,
.dual-tone::after {
content: "";
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.dual-tone::before {
background-color: rgba(40, 80, 160, 0.7); /* 阴影蓝 */
mix-blend-mode: multiply;
}
.dual-tone::after {
background-color: rgba(255, 120, 60, 0.5); /* 高光橙 */
mix-blend-mode: screen;
}
注意:::before 和 ::after 必须在 .dual-tone 内部生效,且不能被 z-index: -1 或 isolation 隔离。
iOS Safari 动画中切换 mix-blend-mode 值会失效
iOS Safari(尤其 14–15 版本)对动态修改 mix-blend-mode 支持极差,切值瞬间混合效果丢失。解决方案很务实:
- 固定用一种模式(如
multiply),改用background-color的 alpha 或 hue 值做动画 - 或改用
opacity控制伪元素可见度,配合预设好的两组颜色 - 避免在
@keyframes中写mix-blend-mode: screen; mix-blend-mode: multiply;这类切换
真正容易被忽略的是:双色调是否成立,不取决于你写了几个 mix-blend-mode,而在于**背后有没有可混合的基色**,以及**两层是否真正重叠绘制**——打开 Chrome DevTools 的 “Rendering” → 勾选 “Paint flashing”,看到红色闪烁才说明混合正在发生。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











