lighten() 和 darken() 函数操作 HSL 明度 L 分量,非 RGB 线性加减;对极值色无效,rgba 颜色先转不透明再计算,百分比参数必须带 %,contrast() 仅二选黑白、不检测 WCAG 对比度。

lighten() 和 darken() 操作的是 HSL 明度,不是 RGB 增减
Less 的 lighten() 和 darken() 不是对 RGB 三通道做线性加减,而是把输入色转成 HSL 后,只调整 L(明度)分量的百分比值。比如 lighten(#0a2b5c, 40%) 是把原色的 L 值 +40 个百分点,而不是“让颜色变亮 40%”。深蓝的 L 原本就低(约 18%),+40 后直接跳到 58%,视觉上可能失去冷感、发灰甚至偏青。
- 对极值色无效:
darken(#000, 20%)还是#000,lighten(#fff, 10%)还是#fff——HSL L 已达边界,无法再调 - 传入 rgba 颜色会先转为不透明等效色再计算,
darken(rgba(0,0,0,0.5), 10%)实际按#000处理,结果仍是#000 - 百分比参数必须带
%符号:lighten(@c, 10)(缺%)会被当数值处理,行为异常
contrast() 返回的是黑白二选一,不是对比度检测
contrast() 本质是判断输入色的明度是否高于阈值(默认 0.43),然后返回你指定的深色或浅色——它不计算 WCAG 对比度,也不考虑 alpha 通道。比如 contrast(rgba(52,152,219,0.8)) 会忽略 0.8,只按 #3498db 的明度算,返回 #fff,但实际在半透背景上,白字可能并不满足 4.5:1。
- 写法错误:漏掉第二、三参数如
contrast(#3498db)等价于contrast(#3498db, #000, #fff),但若背景是灰色系,返回黑/白都可能不可读 - 阈值设太高(如
0.7)会让中明度色全返回深色,导致浅底文字变黑,对比不足 - 旧版 Less(contrast(@bg, @dark, @light, @t) 会编译失败
嵌套调用时空格和括号解析极易出错
Less 解析器对函数嵌套非常敏感,lighten(darken(#3498db,10%),5%) 这种写法会报错,因为它把 darken(#3498db,10%) 当作一个未定义的函数名,而非子表达式。
- 必须在函数名和左括号之间加空格:
lighten( darken(#3498db, 10%), 5%) - 不能换行或 Tab 缩进:
lighten(换行后接darken(...)会中断解析 - 变量参与前必须已定义且类型为 color:
@base: #2ecc71; .btn { background: lighten(@base, 10%); },否则报Operation on an invalid type
mix() 是 RGB 加权平均,不是感知均匀灰阶
mix(@a, @b, 60%) 是按通道做 (0.6×R₁ + 0.4×R₂) 这类线性插值,而人眼对亮度的感知是非线性的(CIELAB L*)。设计工具用 L* 算出的 “70% 白” 在 CSS 里用 mix(white, @color, 70%) 得到的往往更亮,导致配色与设计稿偏差明显。
立即学习“前端免费学习笔记(深入)”;
- 权重顺序不能反:
mix(#007bff, #fff, 20%)是 20% 主色 + 80% 白,不是 20% 白 - 两色明度差过大(如
mix(#000, #ff0, 50%))结果接近灰,饱和度崩塌 - 想模拟设计稿灰阶,别依赖
mix(),改用lightness()提取后手动控制,或直接导出 L* 值转成 HSL
真正麻烦的不是函数本身,而是它们全在编译期固化输出——lighten(#2c3e50, 12%) 一旦编译成 #4a6482,就再也没法在运行时动态响应深色模式切换或用户偏好。需要真·动态的场景,得绕过 Less,用 CSS 自定义属性 + JS 计算。


















