color-mix() 混合白/黑必须使用 oklch 或 lch 空间,srgb 会报错;推荐 oklch 因其明度更符合人眼感知,黑白混合得中性灰;生成 tint/shade 需先转基础色为 oklch,再线性调整 l 值;无自动 fallback,须用 @supports 手动降级;mix-blend-mode 不等价于 color-mix()。

color-mix() 混合白/黑时必须显式指定颜色空间
直接写 color-mix(in srgb, white 70%, black 30%) 会失败——浏览器目前(Chrome 111+、Safari 16.4+)要求必须用支持插值的颜色空间,srgb 不行,得换成 lch 或 oklch。否则控制台报错:Invalid color space in color-mix()。
推荐优先用 oklch:它在明度(L)上更接近人眼感知,黑白混合后灰阶过渡更均匀,不会在暗部“塌陷”或亮部“发飘”。
-
oklch(100% 0 0)是纯白(L=100%,C=0,h 任意) -
oklch(0% 0 0)是纯黑(L=0%,C=0,h 任意) - 混合时只变 L 值,C 和 h 固定为 0,确保结果是中性灰
生成深浅色变体的可靠写法
假设你有一个基础色 #3a5fa8(比如主蓝),想按比例混入白/黑得到浅色版(tint)或深色版(shade),不能直接拿它和黑白混——那会偏色。正确做法是先提取它的明度基准,再在 oklch 空间里线性调整 L 值。
实操分两步:
- 用工具(如 Chrome DevTools 颜色拾取器)把
#3a5fa8转成oklch(L C h),例如得到oklch(55.2% 0.215 252.3) - 浅色变体:提高 L,比如
color-mix(in oklch, oklch(55.2% 0.215 252.3) 60%, oklch(100% 0 0) 40%)→ 更亮但保持色调 - 深色变体:降低 L,比如
color-mix(in oklch, oklch(55.2% 0.215 252.3) 70%, oklch(0% 0 0) 30%)→ 更暗且不发灰紫
注意:百分比总和必须为 100%,且两个颜色都需完整写出 oklch(...) 格式,不能简写为 white 或 black。
兼容性 fallback 必须手动提供
color-mix() 目前无 CSS 级 fallback 机制。如果降级到旧浏览器,CSS 变量会失效,整个声明被忽略。必须用 @supports 包裹,并给外层设兜底值:
button {
--primary: #3a5fa8;
--primary-light: #3a5fa8; /* fallback */
--primary-dark: #3a5fa8;
}
@supports (color: color-mix(in oklch, red, blue)) {
button {
--primary-light: color-mix(in oklch, oklch(55.2% 0.215 252.3) 60%, oklch(100% 0 0) 40%);
--primary-dark: color-mix(in oklch, oklch(55.2% 0.215 252.3) 70%, oklch(0% 0 0) 30%);
}
}
别指望 color-mix() 自动退化成 lighten() 或 darken() —— 那是 Sass 函数,纯 CSS 里不存在。
mix-blend-mode 不是 color-mix() 的替代方案
有人试过用 mix-blend-mode: multiply 叠加白色半透层来“提亮”,这本质是图层混合,依赖背景色,结果不可控:在深色背景上可能变灰,在浅色背景上几乎没变化。而 color-mix() 是纯色计算,输出确定值,和上下文无关。
真正等价的手动实现是:用 JS 把基础色转 oklch,算出目标 L,再转回 sRGB 十六进制——但那就脱离了 CSS 原生能力。所以只要用 color-mix(),就必须接受它对颜色空间的硬性要求和当前有限的浏览器覆盖。
最易被忽略的是:哪怕写了 oklch,如果原始色的 C(色度)太高,混入黑白后可能轻微偏色——这时得先小幅降低 C 再混合,而不是死守原始值。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











