color-mix(in srgb, ...) 不等价于 lighten(),它执行线性插值而非 HSL 明度调整;必须显式声明 in srgb,否则声明失效;百分比表示目标色占比,非提亮幅度;深色模式需手动适配,且生成颜色须实测 WCAG 对比度。

color-mix(in srgb, ...) 不能直接等价于 lighten()
浏览器根本不认识 lighten(),它不是 CSS 函数;color-mix() 也不是它的运行时替代品——它做的是线性颜色插值,不是 HSL 明度通道加法。比如 lighten(#3498db, 15%) 是把 L 值从 50% 加到 65%,而 color-mix(in srgb, #3498db, #fff 15%) 是混合 85% 原色 + 15% 白色,结果更柔和、不易过曝,但数值不对应。你不能指望写个百分比就得到 Sass 编译出的同一色值。
必须显式声明 in srgb,否则静默失效
漏掉 in srgb 是最常踩的坑:Chrome 111+、Firefox 119+、Safari 16.4+ 都要求明确指定色彩空间,否则整条声明被忽略,变量值回退为初始值(甚至变成 inherit),DevTools 里还看不到报错。
-
color-mix(in srgb, var(--base), #fff 20%)✅ 正确 -
color-mix(var(--base), #fff 20%)❌ 无效(缺空间声明) -
color-mix(in rgb, ...)❌ 无效(rgb不是合法空间名)
注意:即使你用 #fff 或 white,也必须写全 in srgb,不能省略。
百分比含义是“目标色占比”,不是“提亮幅度”
color-mix(in srgb, #333, #fff 20%) 表示 80% 的 #333 + 20% 的白色,不是“让 #333 变亮 20%”。这个细节决定你调参时的直觉是否可靠:
立即学习“前端免费学习笔记(深入)”;
- 对深色(如
#1a1a1a)混 15% 白,结果可能是#3d3d3d,视觉上确实“提亮了”,但和lighten(#1a1a1a, 15%)(会报错或 clamp 到灰)完全不同 - 对浅色(如
#f0f0f0)混 20% 白,几乎看不出变化,而lighten()在接近白时直接饱和 - 百分比总和必须为 100%;写成
color-mix(in srgb, #333 80%, #fff)会被自动补足为 20%,但显式写出更安全
深色模式下 white 会翻车,得手动适配
color-mix(in srgb, var(--accent), #fff 20%) 在深色模式下依然加白,结果发灰、对比度崩塌——它不感知 prefers-color-scheme。生产中必须主动降级:
- Chromium 123+ 可用
light-dark(white, black):color-mix(in srgb, var(--accent), light-dark(white, black) 20%) - 更通用方案:用媒体查询重定义变量:
@media (prefers-color-scheme: dark) { :root { --lighten-offset: #1e1e1e; } },再写color-mix(in srgb, var(--accent), var(--lighten-offset) 20%) - 别依赖 JS 注入——CSS 变量在计算阶段就要可用,JS 设置晚于样式解析
真正麻烦的不是怎么写,而是写完之后没人帮你检查 WCAG 对比度。所有 color-mix() 推出的颜色,务必用 DevTools 的无障碍面板实测是否 ≥4.5:1;尤其禁用态文字、小号图标边框这类地方,#000 15% 混出来可能就是纯黑。


















