darken和lighten函数与hsl颜色模式的换算方法

773 阅读1分钟

故事背景是这样的,最近呢,小组在做组件库的升级,隔壁小姐姐负责处理主题色的配置方案,原本已经确定了将UI提供的主题色及其辅色(比如hover、active状态色等)都定义成全局变量,供各个组件使用。

具体大概这样,在varible.styl文件里定义:

$themes_color = #1F86FF

$themes_light_50 = #fff
$themes_light_40 = #ebf4ff
$themes_light_30 = #b8d9ff
$themes_light_20 = #85beff
$themes_light_10 = #52a3ff

$themes_dark_10 = #006deb
$themes_dark_20 = #0056b8
$themes_dark_30 = #003e85
$themes_dark_40 = #002652

可以看到,问题是没问题,但需要维护的色值非常多是不是?这还只是一个蓝色,如果万一假如需要做换肤呢?每一个变量都要改值,那可就太太太太麻烦了!so,我们追求完美的小姐姐决定想想办法……最后,她发现了css提供的darken和lighten函数。

这意味着什么呢?就是我们只需要规定一个$themes_color,然后辅色用darken和lighten函数来分别加深和加浅计算就可以了,这样后期只用维护一个主色变量岂不是爽歪歪?

然鹅,理想很丰满,现实很骨感。我们怎么基于themescolor得到themes_color得到themes_light_10呢?

先来看看lighten函数的用法。

background-color: lighten(hsl(212, 100%, 56%), 10%);
  • color :颜色对象。
  • amount :0 - 100%之间的百分比。
  • 方法:它是可选参数,通过将其设置为相对,用于相对于当前值进行调整。

hsl颜色模式里,h代表色相、s代表饱和度、l代表亮度,而lighten函数的第二个参数所传入的百分比就意味着需要增加的亮度。

那如果我们要给主题色hsl(212, 100%, 56%)提高10%的亮度,达到hsl(212, 100%, 66%)是不是按照lighten(hsl(212, 100%, 56%), 10%)写就可以了呢?

尝试以后发现,这种写法得出的最终色值并非hsl(212, 100%, 66%),这意味着lighten函数的计算与hsl增加亮度的方式不一样。虽然肉眼看也挺和谐,但是UI同学可就不同意了。

哦!救命!还原不了设计稿还不得被揪小辫子?!不行,我的小姐姐同事严谨的工作作风不允许她做不到!!lighten函数这么方便的东东,不可以放弃它!然后,就开始闷头干了~

哦豁~~ 在小姐姐抓耳挠腮之际,我这个半吊子居然靠猜,蒙对了!(可还行?)我墨菲是什么天选之子??

原来,想要基于hsl(212, 100%, 56%)使用lighten函数得到hsl(212, 100%, 66%),必须要经过一系列“复杂”的计算。起初,我在想,这个增加的10%是不是相对于56%,发现死活计算不对,然后试了下相对于100-56,结果居然对了。

66%与56%之间差了10%,我们用这个差值10除以100-56,再乘以100,即可得到lighten第二个参数的值。用计算公式来表达就是(请忽略语法错误):background-color: lighten(hsl(212, 100%, 56%), ((66-56)/(100-56))* 100) + ‘%’;。这样最终产生的色值果然就是hsl(212, 100%, 66%)了。

为了防止偶然性,尝试了76%、86%等多个l亮度百分比,都没毛病,所以可以确定计算正确。

那么darken又是怎么回事呢?

顺藤摸瓜,基于hsl(212, 100%, 56%)使用darken函数得到hsl(212, 100%, 46%),只要这么写就行了:background-color: darken(hsl(212, 100%, 56%), ((56-46)/56 )* 100) + ‘%’;

我们的同事小姐姐当然不会写这样的怪代码,她做的高儿级了一点,styl代码如下:

$themes_black_0 = hsl(212, 100%, 56%) // #1F86FF
$themes_l = 56 // 色值l

minus(a, b)
  a - b
sum(a)
  (a / minus(100, $themes_l)) * 100 + '%'
darksum(a)
  (a / $themes_l) * 100 + '%'

// 变浅   差值/(100-主色l值)  // #1F86FF
$themes_white_30 = lighten($themes_black_0, sum(30)) // +30 #b8d9ff
$themes_white_20 = lighten($themes_black_0, sum(20)) // +20 #85beff
$themes_white_10 = lighten($themes_black_0, sum(10)) // +10 #52a3ff

// 加深   差值/主色l值
$themes_black_10 = darken($themes_black_0, darksum(10)) // -10 #006deb
$themes_black_20 = darken($themes_black_0, darksum(20)) // -20 #0056b8
$themes_black_30 = darken($themes_black_0, darksum(30)) // -30 #003e85

虽然你们也不认识我的同事小姐姐,但也请给她掌声吧吼哈