将SCSS darken函数转为等效color-mix函数的数学原理
用color-mix模拟Sass darken函数的数学原理
假设原有Sass代码:
color: darken(#ABCDEF, 10%);
有人尝试用原生CSS的color-mix替代:
color: color-mix(in srgb, #ABCDEF, #000 10%);
但结果并不匹配——因为Sass的darken函数是基于HSL色彩模型实现的,和RGB空间直接混合黑色的逻辑完全不同。
核心逻辑差异
Sass darken函数的数学逻辑
darken($color, $amount)的本质是在HSL色彩空间内调整:
- 先将输入的RGB颜色转换为HSL模型,提取色相(H)、饱和度(S)、亮度(L)三个分量(亮度L的取值范围为0-1,0代表纯黑,1代表纯白)。
- 保持色相和饱和度不变,将亮度分量降低指定比例:
L' = L * (1 - $amount/100)(比如10%变暗,就是原亮度乘以0.9)。 - 将调整后的HSL值转回RGB颜色,得到最终结果。
color-mix(in srgb, C, #000, p)的数学逻辑
这个操作是在sRGB空间做线性分量混合:
对红、绿、蓝三个分量分别执行:
结果分量 = 原颜色分量 * (1 - p/100) + 纯黑分量(0) * p/100
最终得到的是RGB分量等比例降低后的颜色,这种“变暗”是基于RGB空间的明度,和HSL空间的亮度不是线性对应关系——只有当原颜色是灰度色(R=G=B)时,两者结果才会一致。
如何用color-mix等效表示darken的结果
如果仅已知RGBA值,必须先完成以下转换:
- 将原RGB颜色转换为HSL模型,计算出调整后的亮度值。
- 保持色相、饱和度不变,将调整后的HSL值转回RGB,得到
darken的目标颜色,记为C'。 - 此时等效的color-mix表达式为:
darken(#ABCDEF, 10%) === color-mix(in srgb, #ABCDEF, C', 100%)
或者更直接的,因为C'就是darken的结果,也可以写成:
darken(#ABCDEF, 10%) === color-mix(in srgb, C', #000, 0%)
关键结论:对于非灰度的彩色,无法跳过HSL转换步骤,直接通过原RGB颜色与纯黑/纯白的color-mix来精确模拟Sass darken的效果,两者的色彩空间操作逻辑存在本质差异。
内容的提问来源于stack exchange,提问作者Luke A. Leber
相关产品推荐
相关产品推荐

