lighten() 和 darken() 函数调整的是 hsl 模型中的亮度(l)分量,保持色相与饱和度不变,而非简单加减灰度或混合黑白;其结果符合人眼感知,但需注意边界值、可访问性及运行时限制。

lighten() 和 darken() 函数到底改的是什么
它们不是简单地加减灰度值,而是基于 HSL 色彩模型,在保持色相(H)和饱和度(S)不变的前提下,仅调整亮度(L)分量。这意味着 lighten(#3498db, 10%) 不会把蓝色变成浅灰,而是得到一个更“明亮”的同色系蓝色。
常见误解是认为 lighten() 等价于“加白”,darken() 等价于“加黑”——实际并非如此。Less 内部做的是 HSL 值解析 + L 值线性插值,结果更符合人眼对色彩明暗变化的感知。
为什么用 lightness 而不用 brightness 或 luminance
Less 的 lighten() 和 darken() 操作的是 HSL 中的 L(lightness),不是 HSV 的 V(value),也不是 CIE 的 luminance。这导致两个关键行为:
-
lighten(#000, 20%)得到的是#333,不是#330000(后者是 RGB 加红偏移) - 对高饱和色(如
#ff0000)调用darken(..., 50%)可能直接逼近#000,因为 L 已接近 50%,再减 50% 就归零 - 对已很亮的颜色(如
#f9f9f9)用lighten(..., 10%)会直接 clamp 到#ffffff,不会溢出
lighten() 在真实项目中怎么用才不翻车
它常被用于生成按钮悬停色、禁用态、卡片阴影过渡色,但容易因原始色 L 值过低/过高而失效或突兀:
- 避免对
#000或#fff直接调用 ——lighten(#000, 1%)和darken(#fff, 1%)都只产生极小变化,视觉几乎不可辨 - 慎用于文字颜色:比如
lighten(#333, 40%)得到#b3b3b3,可能低于 WCAG 对比度要求(4.5:1) - 与
saturate()/desaturate()组合使用更可控:例如lighten(desaturate(#e74c3c, 10%), 5%)比单独lighten(#e74c3c, 5%)更柔和 - 推荐搭配变量定义:
@primary: #3498db;<br>@primary-hover: lighten(@primary, 8%);<br>@primary-disabled: desaturate(lighten(@primary, 25%), 30%);
darken() 的兼容性陷阱和替代思路
Less 编译器(尤其是 v3.x+)对 darken() 的实现严格遵循 HSL L 值计算,但某些旧版构建工具(如老版本 gulp-less)可能因依赖的 less.js 版本陈旧,导致结果偏差 ±2%。更隐蔽的问题是:
- 在 CSS 自定义属性(CSS Custom Properties)中无法直接使用
darken()—— 它是 Less 编译期函数,运行时无效 - 若需动态变暗(如主题切换),应改用
color-mix()(现代浏览器)或 HSL 字符串拼接 JS 方案 - 当需要“按比例压暗”而非“固定 lightness 偏移”时,
fadeout(@color, 15%)(降低 alpha)或mix(@color, #000, 15%)(混合黑色)反而更直观可靠
真正难处理的,是那些本身 L 值就接近边界(90%)的颜色 —— 此时 darken() 和 lighten() 的步进感会非常生硬,得手动 fallback 到具体色值或换用 spin()/contrast() 组合。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











