必须将hsl三要素拆为独立变量:--h-primary: 210、--s-primary: 70%、--l-primary: 60%,因var(--color)是字符串不可索引;旧版safari不支持hsl()内calc(),需预计算;只调l值确保明暗阶梯统一,避免跳色;color-mix()比单纯调l更精准生成弱化态与背景色,但需显式声明色彩空间且不支持变量。

必须把HSL三要素拆成独立变量,不能合在一个值里
浏览器不支持对var(--color)做索引式提取,比如var(--color)[2]或calc(var(--color) + 10%)会静默失败——因为--color: 210 70% 60%本质是字符串,不是数组。你得手动拆:--h-primary: 210、--s-primary: 70%、--l-primary: 60%。这样后续所有calc()才真正可控。
常见错误现象:--primary: hsl(210, 70%, 60%)然后在background-color: hsl(from var(--primary) h s calc(l - 10))里用——这在 Safari ≤15.6 中整条声明被忽略,页面直接变透明或继承色。
- 色相
h必须是 0–360 的无单位整数(如210),别写210deg混入单位 - 饱和度
s和亮度l必须带%,漏掉就解析失败 - 旧版 Safari(≤15.4)不支持
hsl()内嵌calc(),必须提前算好存为新变量,如--l-primary-hover: 50%
只调lightness才能保证同色系,别碰hue或saturation做明暗阶梯
人眼对明暗最敏感,固定h和s只动l,所有变体才落在同一视觉轴上:不发灰、不跳色、对比度可预期。一旦同时改s或h,比如hsl(calc(var(--h) + 5), calc(var(--s) - 10%), var(--l)),悬停时按钮可能突然偏紫,浅背景上文字直接不可读。
深色背景上的亮色变体,建议用calc(var(--l-base) - 25%),但下限卡死15%;禁用态可用calc(var(--l-base) + 30%),上限封顶92%。低于12%易失色(尤其高饱和蓝/绿),高于92%会泛白刺眼。
color-mix()比瞎调l更适合生成弱化态和背景色
只靠l值拉高生成浅色背景,高饱和色在l > 85%时已接近白,失去品牌识别度;禁用态若只降l不降s,容易显脏。这时候color-mix(in srgb, var(--primary) 70%, #000 30%)混合黑色,能无损加深且保持色相稳定。
注意:color-mix()不支持变量或currentcolor,权重必须是具体数字,色彩空间必须显式声明(in srgb最稳妥);加起来不必等于 100%,浏览器自动归一化。
- 按钮悬停加深:用
color-mix(in srgb, var(--primary) 80%, #000 20%) - 禁用态弱化:用
color-mix(in srgb, var(--primary) 60%, #ccc 40%)比单纯调l更干净 - 它不能和
oklch()混用——oklch()目前不支持color-mix()
用from + calc()动态衍生颜色时,空格和斜杠一个都不能错
hsl(from var(--primary) h s calc(l - 10))这种写法在 Chrome 111+、Safari 16.4+、Firefox 115+ 可用,但格式极其敏感:hsl(fromvar(--primary)(漏空格)、hsl(from var(--primary) h s l / 0.8)(多斜杠)、hsl(from #3b82f6 h s l, 0.8)(逗号)都会让整条声明被浏览器忽略,且不报错。
互补色必须用hsl(from var(--primary) calc(h + 180) s l),前提是--primary本身是 HSL 格式(如hsl(210, 70%, 60%)),HEX 或 RGB 值会让from提取失败。
兼容性兜底要写两行:color: hsl(210, 70%, 60%)放前面,color: hsl(from var(--primary) calc(h + 180) s l)放后面——旧浏览器跳过第二行,按第一行渲染。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











