color-mix()无法自动生成功能悬停色,仅支持手动指定色彩空间(如in srgb)、字面量颜色及显式权重(如#3b82f6 85%, black 15%),不接受currentColor或CSS变量,且必须配合@supports回退和transition才能在移动端可靠使用。

color-mix() 不能“自动”生成悬停色,它只做一次静态混合——你得手动指定和谁混、混多少、在哪个空间混,否则结果不可控、不一致。
color-mix() 混合必须写全三个硬性参数
浏览器解析 color-mix() 时会严格校验,漏一个就整个声明失效,最终 fallback 到初始色或透明:
-
in srgb或in lch必须显式写出;in srgb兼容性最好(Chrome 111+/Safari 16.4+/Firefox 119+),in lch明度更均匀但 Safari 对它的支持仍有限 - 每个颜色后必须跟百分比权重,且加起来建议显式写成 100%(如
#3b82f6 85%, black 15%);写成#3b82f6 70%, black 30%可以,但#3b82f6, black会默认等比,常导致过暗或发灰 - 颜色只能是字面量:
#2563eb、hsl(220 80% 50%)、rebeccapurple都行;currentColor或var(--primary)会直接报Invalid property value
button:hover 里用 color-mix() 的典型写法
假设按钮默认背景是 #3b82f6(蓝色),想悬停时稳稳加深,不是凭感觉调“暗 20%”,而是用黑色按比例混合:
button {
background-color: #3b82f6;
transition: background-color 0.2s ease;
}
button:hover {
background-color: color-mix(in srgb, #3b82f6 85%, black 15%);
}
注意两点:
立即学习“前端免费学习笔记(深入)”;
- 比例不是通用值:浅色按钮(如
#f0f9ff)可能需要black 30%才明显;深色按钮(如#1e40af)加black 10%就容易发灰,得实机试 -
transition必须写在默认状态(button规则里),不能只写在:hover中;只写transition: all容易触发重排,推荐明确属性
@supports 回退是移动端刚需
Firefox 当前完全不支持 color-mix(),Safari 对 in lch 支持也不稳定。纯靠它会导致部分用户点下去毫无反应:
@supports (color-mix: normal) {
button:hover {
background-color: color-mix(in srgb, #3b82f6 85%, black 15%);
}
}
@supports not (color-mix: normal) {
button:hover {
background-color: #2563eb;
}
}
别用 JS 注入 fallback —— 移动端首屏加载快,CSS 级回退更可靠。如果项目已用 CSS 变量管理主题色,可以把 fallback 色也定义为变量,比如 var(--primary-dark),保持维护一致性。
为什么不能用 currentColor 或 var(--primary)?
这是最容易踩的坑。很多人写 color-mix(in srgb, currentColor 80%, black 20%),以为能复用文字色,结果整条规则被浏览器忽略(截至 2026 年 7 月)。
color-mix() 不接受未计算的变量或动态上下文色。如果你的 --primary 是通过 JS 动态注入或媒体查询切换的,那它在 color-mix() 里依然无效 —— 浏览器运行时根本不会去展开这个变量。
真正能用的,只有编译后已确定的值,比如 var(--primary) 80%, black 20% 前提是 --primary 已被定义为 #3b82f6 这类具体值,且该变量本身不依赖 runtime 计算。


















