CSS原生不支持darken()/lighten(),它们是Sass编译期函数;纯CSS可用hsl()+calc()手动调亮度(兼容性最好)或color-mix()混合黑白(现代浏览器专用),但均需注意色彩空间、单位及WCAG对比度校验。

直接写 darken() 或 lighten() 会失效
浏览器根本不会识别这两个词——它们不是 CSS 语法,而是 Sass 编译期函数。你写 color: darken(#3498db, 15%),CSS 解析器会直接跳过整条声明,或报错“invalid property value”。CSS 变量(如 var(--primary))存的是字符串,不能被运行时“执行”成颜色运算。
用 hsl() + calc() 手动调亮度(兼容性最好)
这是目前最稳妥、支持到 IE11 以外所有现代浏览器的方案,前提是基础色必须用 hsl() 格式定义,并拆成三个变量:
-
--base-h存数字(如204),不带deg -
--base-s和--base-l必须带%单位(如70%、50%) -
calc(var(--base-l) + 10%)合法;calc(var(--base-l) + 10)或calc(var(--base-l) + 10%)混用单位会出错 - L 值超出
0%–100%时浏览器自动 clamp,但结果不可控:比如calc(5% - 10%)→-5%→ 实际取0%,颜色发灰而非预期变暗 - 拼接时注意单位:
hsl(var(--base-h), var(--base-s), calc(var(--base-l) - 10%)),S 参数需保留%
用 color-mix() 混合黑白(现代浏览器专用)
color-mix() 是 CSS Color Level 4 的新特性,在 Chrome 111+、Firefox 119+、Safari 16.4+ 可用,语义更直观,但行为与 Sass 不同:
- 它在
srgb空间线性插值,不是 HSL 亮度通道调整,对深色“提暗”更柔和,不易突变成纯黑 - 写法简洁:
--darker: color-mix(in srgb, var(--base-color), #000 15%)表示加 15% 黑色 - 不要省略
in srgb—— 缺失时部分浏览器会降级为默认色彩空间,结果偏差大 - 基础色可用
#3498db、rgb()或hsl(),无需预先拆解 - 它不等价于
darken($color, 15%),尤其对高饱和色,结果偏灰而非保色相
别用 filter: brightness() 或蒙层模拟
看似简单,但完全偏离设计意图:
立即学习“前端免费学习笔记(深入)”;
-
filter: brightness(0.8)是渲染后滤镜,不改变颜色语义值:无障碍工具读不到真实色值,WCAG 对比度校验失效 -
opacity: 0.8同时削弱 alpha 和所有通道,破坏文本/边框的可访问性对比度 - 叠加
rgba(0,0,0,0.2)蒙层在多层叠加时易产生意外色偏,且无法用于border-color、text-shadow等需要纯色值的属性 - 这些方法生成的不是独立颜色变量,只是视觉覆盖效果
真正麻烦的不是怎么算,而是算完之后没人帮你检查对比度——color-mix(in srgb, #1a1a1a, #000 20%) 可能产出接近 #000000 的色值,文字直接消失。所有推导出的颜色,务必用 DevTools 的无障碍面板手动验证是否 ≥4.5:1。


















