必须用 lightness() 函数判断明暗,因其已做感知加权且支持所有合法颜色(含 alpha);rgb 通道直接比较违背视觉一致性,如浅蓝 #3498db 的 lightness 约 38,应属深色背景。

直接用 lightness() 函数,临界值设为 40–45,别碰 red()/green() 或自造 luminance 公式——SCSS 原生这个函数已做感知加权,且对所有合法颜色(包括带 alpha 的 hsla())都可靠。
为什么必须用 lightness() 而不是 RGB 通道判断
常见错误是写 if(red($c) > 128 and green($c) > 128 and blue($c) > 128),这会把浅蓝(#3498db)误判为“亮色”,实际人眼感知它是偏暗的。因为 RGB 三通道权重不同,简单比较或平均完全违背视觉一致性。
-
lightness(#3498db)返回约 38,正确归入深色背景范畴 -
lightness(hsla(0, 0%, 50%, 0.3))仍返回 50 —— 透明度不影响结果,无需额外处理 alpha - 它支持全部 CSS 颜色字面量:
#fff、rgb(30, 40, 50)、rebeccapurple、hsl(200, 100%, 60%)
封装可复用的 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); - 不要在
@each循环里嵌套调用该函数生成样式类——编译期虽无性能问题,但调试时难以定位哪次调用出错 - 若主题色来自 JSON 导入等动态源,则必须用函数;若为静态变量,更推荐提前计算好配套文字色变量(见下一条)
批量处理主题色组:优先预定义文字色变量
当有 $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.1:1,低于 AA 标准(4.5:1)。需要高保真适配时,得换 JS 实时算 luminance 或用 color-contrast()(目前仅 Safari 17.4+ 和 Chrome 127+ 支持)。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











