你以为 CSS 只能显示颜色?今天 color-mix() 把颜色运算做进了浏览器里
设计师给你一套 Design Token,深色主题的 brand primary 是 #6366f1,hover 态要在这个基础上加深 20%。你的做法是什么?
大多数人选择靠手算,或者直接写死一个新色值。但这两种做法都有问题:手算容易偏,算出来的色值还和原始色板脱离了关系,下次 brand primary 一变,hover 态就再也追不上了。
CSS 颜色混合函数 color-mix() 就是来解决这个问题的。 它把两种颜色的混合运算做进了浏览器里,不需要任何构建步骤,不需要 JS,直接写一句 CSS 就够了。
语法长这样:
.button {
/* 在 oklch 色彩空间里,把 --brand 和 --bg 按 70%:30% 混合 */
background: color-mix(in oklch, var(--brand) 70%, var(--bg));
}
这里 –brand 和 –bg 可以是你已有的任何颜色变量,混合比例 70% 和 30% 决定最终结果偏向哪边。你可以把它理解为「CSS 里的调色盘」,只不过调色盘在浏览器里实时运行。
color-mix() 有几个关键细节需要知道:
色彩空间决定混合结果。 in oklch 是目前最推荐的选择,因为 OKLCH 是感知均匀的色彩空间——混合结果在人眼看来是「均匀过渡」的,不会出现那种灰色偏粉或者蓝色发紫的问题。如果你在 srgb 或 display-p3 空间里混合,比例稍大一些就会出现明显的色相偏移。
/* OKLCH:感知均匀,混合自然 */
color-mix(in oklch, #6366f1 70%, #ffffff)
/* srgb:容易偏色,不推荐 */
color-mix(in srgb, #6366f1 70%, #ffffff)
插值模式决定怎么混合。 除了直接混合,CSS 还支持 in hue 模式,只混合色相通道,保留亮度和饱和度。这个在设计系统里做色相变体(variants)特别有用,比如从蓝色主题变到紫色主题:
/* 只改变色相,亮度饱和度保持不变 */
color-mix(in oklch, in hue, var(--brand) 70%, #8b5cf6)
浏览器支持方面, color-mix() 已经进入 Baseline 2023,Chrome 111+、Safari 16.2+、Firefox 113+ 全球覆盖率超过 90%,生产可用,不需要任何 Polyfill。
实际使用场景:
做主题切换是最直接的用途。深色模式下,你不需要维护两套完整的颜色变量,只需要一个亮色主色,然后让暗色变量通过混合得到:
:root {
--brand: #6366f1;
}
[data-theme="dark"] {
/* 把品牌色和深色背景混合,得到暗色版本 */
--brand: color-mix(in oklch, var(--brand) 15%, #0f172a);
}
当品牌色更新时,暗色版本自动跟着变,不需要手动调整两套值。
做 Hover/Active 态也常用这个模式:
.button {
background: var(--brand);
}
.button:hover {
/* 混合黑色,把背景压暗 15% */
background: color-mix(in oklch, var(--brand) 85%, #000);
}
.button:active {
/* 混合白色,把背景提亮 10% */
background: color-mix(in oklch, var(--brand) 90%, #fff);
}
如果你的项目还在用 Sass/Less 的 darken() / lighten() 函数,color-mix() 是可以直接替代的。 构建时运算变成了运行时渲染,但输出结果更准确,更重要的是——变量和混合结果之间的派生关系现在是显式的、可追踪的。
下一步你可以做的是:找一件你现在正在手动维护的派生色(比如 hover 态、disabled 态、深色变体),把它改成 color-mix(),看看维护成本降了多少。
评论区
登录后可评论。