必须用 lightness() 判断明暗,因其已做感知加权且兼容所有合法颜色;错误做法如直接比较 RGB 通道会导致视觉不一致,例如浅蓝 #3498db 被误判为亮色,而 lightness() 正确返回约 38;透明度不影响结果,可封装为 text-color-for() 函数统一处理。

直接用 lightness() 判断,临界值设为 45;别碰 RGB 拆通道、contrast() 或自造 luminance 公式——它已做感知加权,且对所有合法颜色(含 hsla())都可靠。
为什么必须用 lightness() 而不是 red()/green() 比较
常见错误是写 if(red($c) > 128 and green($c) > 128),这会把浅蓝 #3498db(人眼感知偏暗)误判为“亮色”。因为 RGB 三通道权重不同,简单比较完全违背视觉一致性。lightness(#3498db) 返回约 38,正确归入深色背景范畴。lightness(hsla(0, 0%, 50%, 0.3)) 仍返回 50 —— 透明度不影响结果,无需额外处理 alpha。
封装可复用的 text-color-for() 函数
把判断逻辑收进函数,避免每个地方重复写 if。注意返回值必须是颜色值(不是字符串),且不能传变量名字符串(如 "primary")。
@function text-color-for($bg) {
@return if(lightness($bg)
- 调用时直接传颜色值:
color: text-color-for($theme-primary)或color: text-color-for(#2c3e50) - 若主题色来自 JSON 导入等动态源,则必须用函数;若为静态变量,更推荐提前计算好配套文字色变量(见下一条)
- 不要在
@each循环里嵌套调用该函数生成样式类——编译期虽无性能问题,但调试时难以定位哪次调用出错
批量处理主题色组:优先预定义文字色变量
当有 $theme-primary、$theme-success 等一组主题色时,硬编码多个 if 或反复调用函数都不如一次性定义对应文字色变量。
$theme-primary: #3498db; $text-primary: text-color-for($theme-primary); $theme-success: #2ecc71; $text-success: text-color-for($theme-success);
- 后续使用语义清晰:
color: $text-success - 方便覆盖:想让所有 success 文字强制用
#212529?只改一行$text-success: #212529 - 不支持运行时求值,所以
text-color-for("primary")这种写法无效——SCSS 不解析字符串为变量名
真正容易被忽略的是:这个方案只解决「明暗倾向」,不保证 WCAG 对比度达标。比如 lightness(#8e44ad) ≈ 42,函数会返回 #fff,但 #8e44ad 与 #fff 的对比度仅约 3.8,低于 AA 级要求的 4.5。需要真对比度检查,得上 relative-luminance() + contrast-ratio() 函数组合,或交由 JS 在运行时处理。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











