各位观众老爷,大家好!今天咱们来聊聊CSS的未来战士——relative-color-syntax
,也就是“相对颜色语法”。这玩意儿如果真能普及开来,那CSS玩颜色就彻底支棱起来了!
啥是相对颜色语法?
简单来说,就是你可以基于一个已有的颜色,通过一些操作,动态地生成一个新的颜色。听起来是不是有点像Photoshop里的颜色调整?没错,就是那个味儿!
想想以前,你想把一个按钮的颜色稍微调亮一点,要么用Sass的lighten()
函数,要么就得吭哧吭哧地手动改hex值。现在有了相对颜色语法,就可以直接在CSS里完成,代码更简洁,也更容易维护。
语法初探
相对颜色语法的基本结构是这样的:
color: color( <reference-color> calc(<channel-adjustment>));
<reference-color>
:这是你要参考的颜色,可以是hex值、rgb值、hsl值等等,甚至是CSS变量!calc(<channel-adjustment>)
:这是个关键!calc()
函数里面是你对颜色通道(比如红、绿、蓝)的具体调整。
举个例子,假设你想让一个元素的背景色比它的文本颜色稍微亮一点:
p {
color: rgb(100, 150, 200); /* 原始文本颜色 */
background-color: color(currentColor calc(red() + 20) calc(green() + 20) calc(blue() + 20)); /* 背景色比文本颜色更亮 */
}
这里,currentColor
表示当前元素的文本颜色,red()
、green()
、blue()
分别提取出红、绿、蓝通道的值,然后用calc()
函数给每个通道加上20,就得到了一个更亮的背景色。
颜色通道函数
上面例子里用到了red()
、green()
、blue()
这些函数,它们就是用来提取颜色的各个通道值的。除了这三个,还有很多其他的通道函数,它们才是相对颜色语法的核心武器!
下面这张表列出了一些常用的通道函数:
函数 | 描述 | 示例 |
---|---|---|
red() |
获取颜色的红色通道值(0-255 或者 0%-100%) | color(red 255) 将红色通道设置为 255 |
green() |
获取颜色的绿色通道值(0-255 或者 0%-100%) | color(green 100%) 将绿色通道设置为 100% |
blue() |
获取颜色的蓝色通道值(0-255 或者 0%-100%) | color(blue calc(blue() * 0.5)) 将蓝色通道值减半 |
alpha() |
获取颜色的透明度(0-1) | color(alpha 0.5) 将透明度设置为 50% |
hue() |
获取颜色的色相(0-360 度) | color(hue calc(hue() + 30deg)) 将色相旋转 30 度 |
saturation() |
获取颜色的饱和度(0%-100%) | color(saturation calc(saturation() * 1.2)) 将饱和度增加 20% |
lightness() |
获取颜色的亮度(0%-100%) | color(lightness calc(lightness() + 10%)) 将亮度增加 10% |
whiteness() |
获取颜色的白度(0%-100%) (仅在 oklch 和 oklab 颜色空间中使用) |
color(oklch lightness calc(lightness() + 5%) whiteness calc(whiteness() - 2%)) 在 oklch 颜色空间中,增加亮度并减少白度 |
blackness() |
获取颜色的黑度(0%-100%) (仅在 oklch 和 oklab 颜色空间中使用) |
color(oklch lightness calc(lightness() - 5%) blackness calc(blackness() + 2%)) 在 oklch 颜色空间中,减少亮度并增加黑度 |
lch() |
获取颜色的 LCH 值(亮度、色度、色相) (仅在 lch 颜色空间中使用) |
color(lch lightness calc(lch() * 1.1) chroma calc(chroma() * 0.9)) 在 lch 颜色空间中,增加亮度并减少色度 |
oklch() |
获取颜色的 OKLCH 值(感知均匀的亮度、色度、色相) | color(oklch lightness calc(oklch() * 1.1) chroma calc(chroma() * 0.9)) 在 oklch 颜色空间中,增加亮度并减少色度 |
lab() |
获取颜色的 LAB 值(亮度、a 分量、b 分量) (仅在 lab 颜色空间中使用) |
color(lab lightness calc(lab() * 1.1) a calc(a() * 0.9)) 在 lab 颜色空间中,增加亮度并减少 a 分量 |
oklab() |
获取颜色的 OKLAB 值(感知均匀的亮度、a 分量、b 分量) | color(oklab lightness calc(oklab() * 1.1) a calc(a() * 0.9)) 在 oklab 颜色空间中,增加亮度并减少 a 分量 |
cielab() |
获取颜色的 CIELAB 值(亮度、a 分量、b 分量) (已弃用,建议使用lab() 或oklab() ) |
color(lab lightness calc(lab() * 1.1) a calc(a() * 0.9)) 在 lab 颜色空间中,增加亮度并减少 a 分量 |
cielch() |
获取颜色的 CIELCH 值(亮度、色度、色相) (已弃用,建议使用lch() 或oklch() ) |
color(lch lightness calc(lch() * 1.1) chroma calc(chroma() * 0.9)) 在 lch 颜色空间中,增加亮度并减少色度 |
hwb() |
获取颜色的 HWB 值(色相、白度、黑度) | color(hwb hue calc(hue() + 10deg) whiteness calc(whiteness() + 5%) blackness calc(blackness() - 5%)) 色相旋转 10 度,增加白度并减少黑度 |
l() |
获取颜色的亮度值(仅在 lch 和 lab 颜色空间中使用,可以理解为 lightness() 的别名) |
color(lch l calc(l() + 10%) chroma calc(chroma() * 0.9)) 在 lch 颜色空间中,增加亮度并减少色度 |
a() |
获取颜色的 a 分量值(仅在 lab 颜色空间中使用,表示颜色在绿-红轴上的位置) |
color(lab l calc(l() + 5%) a calc(a() - 10)) 在 lab 颜色空间中,增加亮度并减少 a 分量(颜色更偏向绿色) |
b() |
获取颜色的 b 分量值(仅在 lab 颜色空间中使用,表示颜色在蓝-黄轴上的位置) |
color(lab l calc(l() + 5%) b calc(b() + 10)) 在 lab 颜色空间中,增加亮度并增加 b 分量(颜色更偏向黄色) |
c() 或chroma() |
获取颜色的色度值(仅在 lch 颜色空间中使用,表示颜色的鲜艳程度) |
color(lch l calc(l() + 5%) c calc(c() * 0.8)) 在 lch 颜色空间中,增加亮度并减少色度(颜色更柔和) |
颜色空间
注意到上面表格里提到了 oklch
、oklab
、lch
、lab
等等,这些就是颜色空间。不同的颜色空间用不同的方式来描述颜色,它们各有优缺点。
- RGB: 最常见的颜色空间,用红、绿、蓝三个通道来表示颜色。简单直接,但是不太符合人类对颜色的感知。
- HSL: 用色相、饱和度、亮度来表示颜色。比RGB更符合人类直觉,但是亮度通道的感知并不均匀。
- LCH 和 LAB: 基于CIE Lab颜色模型,旨在提供感知均匀的颜色空间。LCH 使用亮度(L)、色度(C)和色相(H),而 LAB 使用亮度(L)以及 a 和 b 分量(分别代表绿-红轴和蓝-黄轴)。
- OKLCH 和 OKLAB: 被认为是目前感知最均匀的颜色空间。OKLCH 是 LCH 的改进版本,OKLAB 是 LAB 的改进版本。在颜色操作和渐变中能提供更自然和一致的结果。
- HWB: 用色相、白度、黑度来表示颜色。更适合用于创建基于白或黑的颜色变体。
选择合适的颜色空间很重要,尤其是在做复杂的颜色调整时。oklch
和 oklab
通常是更好的选择,因为它们能提供更平滑、更自然的颜色过渡。
实战演练
光说不练假把式,咱们来几个实际的例子:
1. 创建一个悬停效果:
button {
background-color: #4CAF50; /* 原始颜色 */
}
button:hover {
background-color: color(#4CAF50 lightness(calc(lightness() + 10%))); /* 悬停时亮度增加10% */
}
2. 创建一个阴影效果:
.shadow {
background-color: #f0f0f0;
box-shadow: 0 2px 5px color(#000 alpha(calc(alpha() * 0.2))); /* 黑色阴影,透明度为20% */
}
3. 基于CSS变量动态调整颜色:
:root {
--primary-color: #2196F3;
}
.element {
background-color: var(--primary-color);
color: color(var(--primary-color) lightness(calc(lightness() + 60%))); /* 文本颜色比背景色更亮 */
}
4. 使用 oklch
创建更柔和的颜色变化:
.brand-color {
background-color: oklch(60% 0.2 240); /* 定义一个品牌颜色 */
color: color(oklch(60% 0.2 240) lightness(calc(lightness() * 0.8))); /* 基于品牌颜色,创建一个更暗的文本颜色 */
}
5. 实现主题切换
结合CSS自定义属性,相对颜色语法可以方便地实现主题切换。
:root {
--base-color: #29abe2; /* Sky Blue */
}
body {
background-color: var(--base-color);
color: color(var(--base-color) lightness(calc(lightness() * 0.9)) saturation(calc(saturation() * 0.8))); /* 更暗更柔和的文字颜色 */
}
/* 深色主题 */
body.dark-theme {
--base-color: #2c3e50; /* Midnight Blue */
}
在这个例子中,我们定义了一个 --base-color
变量作为基础颜色。然后,我们使用相对颜色语法基于这个基础颜色生成文字颜色,使其在任何主题下都与背景色形成良好的对比。通过切换 body
的 dark-theme
类,我们可以轻松地切换主题,而文字颜色会自动调整。
注意事项
- 浏览器兼容性: 相对颜色语法还是个新东西,目前(2024年)的浏览器支持情况还不是特别好。在使用前,最好查一下Can I Use,并做好降级方案。
- 性能: 复杂的颜色计算可能会影响性能。尽量避免在动画中使用过于复杂的相对颜色语法。
- 可读性: 虽然相对颜色语法很强大,但是过度使用可能会降低代码的可读性。要适度使用,并添加必要的注释。
- 单位: 确保在
calc()
函数中使用正确的单位。例如,角度使用deg
,百分比使用%
。
总结
相对颜色语法是CSS颜色处理的一次重大升级。它让我们可以更灵活、更动态地控制颜色,减少了对预处理器和JavaScript的依赖。虽然目前还处于发展阶段,但是相信在不久的将来,它一定会成为CSS开发者的必备技能。
彩蛋
最后,给大家分享一个好玩的小技巧。你可以用相对颜色语法来创建一个简单的颜色反转效果:
.invert {
background-color: #ff0000; /* 红色 */
color: color(white red(calc(255 - red())) green(calc(255 - green())) blue(calc(255 - blue()))); /* 反转后的颜色 */
}
这段代码会将背景色反转,得到青色。是不是很有趣?
好了,今天的分享就到这里。希望大家有所收获!如果有什么问题,欢迎在评论区留言。咱们下期再见!