摘要
你知道在前端项目定义的颜色色板能影响网站的消耗吗?即使是相对更环保的颜色选择也能减少对移动设备电池寿命的影响。
本篇文章,Michelle Barker分享了一些在CSS中使用颜色时你必须记住的但容易忽视的建议。
网页上的色彩远比人们看到的要丰富,也更有趣!今天,我们来看看在设计系统中关于颜色的最佳实践,以及在不久的将来我们可以从颜色中有何种期待。
常见的颜色值
在CSS中有很多方式定义颜色,类似CSS named colors是颜色命名最简单方法之一。
.my-element { background-color: red; } 复制代码
但这有一定的局限性,并且很难适应我们的设计系统!我们可以使用HEX(十六进制)颜色
,十六进制颜色码也可以给页面元素赋予背景颜色:
.my-element { background-color: #ff0000; } 复制代码
除非你是颜色专家,否则看到HEX颜色码会无法反应出元素所渲染出的颜色,这较为难以理解。当我们建网站时,设计师可能会给我们一个十六进制颜色值,但如果他们要求基于这个值变暗20%,没有可视化工具或颜色选择器的话,我们很难通过调整这个hex值来达到设计师的需求。
RGB
RGB (red, green, blue)
表示法是是另一种颜色书写方式,以一种可读性更强的形式去访问与HEX颜色码相同的颜色。在CSS中使用rgb()
函数表示这种值。网页上的颜色是可叠加的,意味着红、绿、蓝的比例越高,最终的颜色越亮。如果我们只使用红色这个颜色通道,那么最终颜色就是红色的。
.my-element { background-color: rgb(255, 0, 0); } 复制代码
如果红、绿、蓝这三个颜色通道的值设置到最大,那么最终颜色是白色:
.my-element { background-color: rgb(255, 255, 255); } 复制代码
此外,还可以用rgba()
函数,其中alpha
属性表示透明度:
.my-element { background-color: rgba(255, 0, 0, 0.5); // transparency of 50% } .my-element { background-color: rgba(255, 0, 0, 1); // fully opaque } 复制代码
rgb()
函数和rgba()
函数在某些程度上允许开发者在代码上“混合”颜色,但结果可能有点不可预测。
HSL
如今,我们已经可以在CSS中利用hsl()
函数和hsla()
函数使用HSL(hue, saturation, lightness)
值,作为一名开发者,当需要调整颜色值时,这种方式更加直观。例如,我们可以通过调整lightness
参数来获得一个颜色的深色变体和浅色变体。
hue
、saturation
、lightness
分别表示色相、饱和度、亮度
.my-element { background-color: hsl(0deg, 100%, 20%); // dark red } .my-element { background-color: hsl(0deg, 100%, 50%); // medium red } .my-element { background-color: hsl(0deg, 100%, 80%); // light red } 复制代码
hue
参数表示在色轮上的位置,从0到360,-0(或360)是红色的,120是绿色的,240是蓝色的。
.my-element { background-color: hsl(180deg, 50%, 50%); } .my-element { background-color: hsl(0.5turn, 50%, 50%); } .my-element { background-color: hsl(180, 50%, 50%); } 复制代码
Tip:在Chrome和Firefox浏览器的开发者工具中,按住
shift
键并点击颜色样本检查器,可以在十六进制、RGB和HSL之间切换颜色值!网络异常,图片无法展示|
hsl()
和 hsla()
函数很适合自定义属性。
currentColor
currentColor
关键字是另一种设置元素颜色的方法。它允许我们用元素的文本颜色来作为变量。虽然跟自定义属性对比起来有一些使用上的局限性,但它经常会被用来设置SVG图标的填充颜色,以此来确保他们能够与父元素的文本颜色相一致。更多详情看:Cascading SVG Fill Color
现代颜色语法
CSS Color Module Level 4提供了更为方便的颜色函数语法,被广泛应用于浏览器。其中提到,函数中的参数不需要再以逗号进行分割,hsl()
和rgb()
函数提供了alpha
参数,它是一个可选参数,用正斜杠分割:
.my-element { /* optional alpha value gives us 50% opacity */ background-color: hsl(0 100% 50% / 0.5); } .my-element { /* With no alpha value the background is fully opaque*/ background-color: hsl(0 100% 50%); } 复制代码
新的CSS颜色函数
HWB
HWB (hue,whiteness and blackness)
表示色相、白色浓度、黑色浓度。跟HSL一样,色相值可以是0-360度数,其他两个参数则是控制此色相中应该混合多少白色和黑色(白色浓度跟黑色浓度可以直接导致最后结果是全白还是全黑)。如果白色浓度跟黑色浓度的比例越接近,越会增加灰调。这跟调色一样,对于创建单色板特别管用。
可以在codepen上玩一下这个函数(支持Safari)。
LAB
LAB
和LCH
在规范中视为是与设备无关的颜色。LAB
是一个可以在Photoshop
等软件中使用的颜色空间。如果想要一种颜色在屏幕上看起来与你所穿的T恤上的颜色一样,LAB
是值得推荐的。
LAB颜色模式有三个轴(参数):
- lightness:取值范围为0~100,表示亮度。与lab()函数一起使用时,亮度可以超过100%。超亮的白色可以使用高达400%的比例。
- a分量:代表由绿色到红色的光谱变化,取值范围均为-120~120
- b分量:代表由蓝色到黄色的光谱变化,取值范围均为-120~120 a与b,两个负值可以让一个颜色朝向光谱的绿色/蓝色末端,两个正值可以指向更橙/红的色调
.my-element { background-color: lab(80% 100 50); // reddish pink } .my-element { background-color: lab(80% -80 -100); // blue/turquoise } 复制代码
LCH
LCH(lightness, chroma, and hue)
代表亮度、饱和度和色相。与HSL类似,色相范围值是0~360。饱和度代表着颜色树枝,我们可以看作类似于HSL中的饱和度,
- lightness:跟LAB一样,可以是一个超过100%的百分比。
- chroma:色彩的相对饱和度(相对暗的颜色可以取到的最大饱和度要小一些)。类似于HSL中的饱和度,但chroma可以超过100——事实上,,理论上它是无界的
- hue:与HSL类似,范围值是0~360
.my-element { background-color: lch(80% 100 50); } .my-element { background-color: lch(80% 240 50); // this color would be outside of the displayable range of today’s browsers } 复制代码
然而,现代浏览器和显示器可以显示的颜色数量是有限制的(后面会有介绍),所以值超过230就没有什么变化了。
有了LAB和LCH,为何还要有HSL?
其中一个原因是,使用LAB或LCH,可以获得更大范围的颜色。LAB和LCH的设计是为了让我们能够接触到人类视觉的整个光谱。
此外,HSL和RGB也有一些缺点:它们在感知上不是统一的。在HSL中,根据hue色相的不同,增加或减少亮度最终导致的结果也会有很大的不同。
在这个demo中,通过点击灰度切换按钮,可以看到LCH和HSL的鲜明对比。
对于HSL的hue色相和saturation饱和度,尽管hsl函数中的lightness参数
相同,但每个正方形的感知亮度都存在明显差异!同时,对于LCH中的chroma和hue色相几乎有着一致的感知亮度。
当我们使用LCH颜色作为渐变色时,我们也可以看到很大的不同。这个demo中,首尾的颜色是一样的(可以使用这个工具将LCH值切换为HSL值),但是当在渐变过程中有所差异:LCH中间经历了明显的蓝调和紫调,而LCH中会比较浅一些。
LAB和LCH虽然在语法上可能不那么直观,但它们的行为对人眼来说更有意义。在LCH colors in CSS: what, why, and how?这篇文章中,解释了LCH颜色模式的优点,作者也设计了一个LCH颜色工具。
与其他颜色函数一样,hwb()、lab()和lch()也接受一个可选的alpha参数:
.my-element { background-color: lch(80% 240 50 / 0.5); // Resulting color has 50% opacity } 复制代码
浏览器兼容性和颜色空间
hwb()
、lab()
和lch()
目前仅Safari浏览器支持。如果必须要使用的话,这里对于不支持的浏览器有个备选方案,使用工具LCH Colour Picker将lch颜色转换成rgb颜色
.my-element { background-color: lch(55% 102 360); /* LCH color converted to RGB using Lea Verou’s tool: https://css.land/lch/ */ background-color: rgb(98.38% 0% 53.33%); } 复制代码
如果样式依赖于支持的较新颜色功能,我们可以使用功能查询:
.my-element { display: none; } /* Only display this element if the browser supports lch() */ @supports (background-color: lch(55% 102 360)) { .my-element { display: block; background-color: lch(55% 102 360); } } 复制代码
值得注意的是,正如Lea在文章中解释的那样,尽管现代屏幕能够显示RGB以外的颜色,但大多数浏览器目前只支持sRGB颜色空间内的颜色。在LAB颜色演示中,你可能会注意到,将滑块移动到某个点之外实际上不会影响颜色,即使在支持LAB()和lch()的Safari中也是如此。使用超出sRGB范围的值只有在硬件和浏览器充分发展时才会产生效果。
Safari现在支持color()
函数,这使我们能够在P3空间中显示颜色,但目前这些颜色仅限于RGB颜色,并且还没有为我们提供LAB和LCH的所有优势。
.my-element { background: rgb(98.38% 0% 53.33%); // bright pink background: color(display-p3 0.947 0 0.5295); // equivalent in P3 color space } 复制代码
推荐阅读:Nikita Vasilyev的《Wide Gamut Color in CSS with Display-P3》
可用性
一旦LAB和LCH得到广泛支持,它们能够让我们更易组合颜色。前景文本应该与具有不同hue色相和chroma饱和度不同的背景色有着相同对比度,只要他们的亮度值保持不变。目前HSL颜色的情况肯定不是这样。
颜色管理
广泛使用颜色函数,意味着我们在应用程序中管理颜色时有更多选择。在我们的设计系统中,通常需要几种给定颜色的变体,从深色到浅色不等。
自定义属性
CSS支持自定义属性,这就使得在样式表中可以复用值。由于允许部分特性值,因此对于管理和操作颜色值是极其有用的。由于其直观性,HSL特别适合自定义属性。在上一个demo中,通过计算基于元素索引值(在另一个自定义属性中定义)的hue色相值,来调整色带每个部分的色调。
li { --hue: calc(var(--i) * (360 / 10)); background: hsl(var(--hue, 0) 50% 45%); } 复制代码
我们还可以做一些事情,比如计算互补色(来自色轮两侧的颜色)。关于这一点,已经写了很多文章,所以不会在这里讨论老话题,但如果你感兴趣,推荐这个文章:On Switching from HEX & RGB to HSL
从HEX/RGB迁移到HSL
RGB颜色可能在一定程度上满足您的需求,但如果您需要灵活性,以便能够从基本调色板衍生出新的色调,那么最好切换到HSL(或LCH,一旦支持)。为此,建议采用定制属性。
Tips: 有大量在线资源可用于将十六进制或RGB值转换为HSL:Color tools
也许您将颜色存储为Sass变量:
$primary: rgb(141 66 245); 复制代码
当转换为HSL时,我们可以为色调、饱和度和亮度值指定自定义属性。这使得创建原色的深色或浅色、或多或少饱和的变体变得容易。
:root { --h: 265; --s: 70%; --l: 50%; --primary: hsl(var(--h) var(--s) var(--l)); --primaryDark: hsl(var(--h) var(--s) 35%); --primaryLight: hsl(var(--h) var(--s) 75%); } 复制代码
HSL对于创建配色方案非常有用,亚当·阿盖尔(Adam Argyle)的《构建配色方案》(Building a color Scheme)一文对此进行了详细介绍。在这篇文章中,他以品牌颜色为基础,创建了浅色、深色和暗淡的配色方案。我喜欢这种方法,因为它允许对颜色变量进行一些细粒度的控制(例如,在“暗”方案中降低颜色的饱和度),但仍然保留了定制属性的巨大优势:只在一个地方更新品牌颜色将执行到所有颜色方案,因此它可能会在未来为我们节省大量工作。
SASS颜色函数
当涉及到混合和调整颜色时,Sass提供了颜色功能,使我们能够多年来做到这一点。我们可以饱和或去饱和,变亮或变暗,甚至将两种颜色混合在一起。它们在某些情况下非常有效,但也有一些局限性:首先,我们只能在编译时使用它们,不能在浏览器中实时操纵颜色。其次,它们仅限于RGB和HSL,因此它们也面临着同样的感知一致性问题,正如我们在本演示中看到的,在本演示中,一种颜色越来越不饱和,但在转换为灰度时却显得越来越亮。
为了确保亮度保持一致,我们可以用与上面HSL类似的方式使用LCH的自定义属性。
li { --hue: calc(var(--i) * (360 / 10)); background: lch(50% 45 var(--hue, 0)); } 复制代码
色彩混合与操纵
混色
CSS还不允许我们在浏览器中混合颜色。这一切都将发生变化:CSS5颜色规范(工作草案)包含了颜色混合功能的建议,听起来相当有前途。第一个是color-mix()
函数,它混合了两种颜色,很像Sass的mix()
函数。但是CSS中的color-mix()
允许我们指定一个颜色空间,并在默认情况下使用LCH,因此具有更好的混合效果。
Tips:在Safari 15中,color-mix()
和color-contrast()
现在可以使用!查看这篇关于如何在Safari中启用实验功能的文章:appademic.tech/safari-hidd…
当作为参数传入时,颜色也不必是LCH,但插值将使用指定的颜色空间。我们可以指定每种颜色的混合量,类似于渐变停止:
.my-element { /* equal amounts of red and blue */ background-color: color-mix(in lch, red, blue); } .my-element { /* 30% red, 70% blue */ background-color: color-mix(in lch, red 30%, blue); } 复制代码
颜色对比度和可访问性
color-contrast()
是另一个被提出的函数,它确实对挑选可访问的颜色有很大的影响。事实上,它的设计首先考虑了可访问性。它允许浏览器通过与其他颜色进行比较,从列表中选择最合适的值。我们甚至可以指定所需的对比度,以确保我们的配色方案符合WCAG指南。颜色从左到右计算,浏览器从列表中选择符合所需比例的第一种颜色。如果没有符合比例的颜色,所选颜色将是对比度最高的颜色。
.my-element { color: wheat; background-color: color-contrast(wheat vs bisque, darkgoldenrod, olive, sienna, darkgreen, maroon to AA); } 复制代码
因为现在任何浏览器都不支持这一点,所以直接从规范中借用了这个示例。当浏览器计算表达式时,得到的颜色将是深绿色,因为与文本的颜色小麦相比,它是第一个满足AA对比度的颜色。
浏览器兼容性
CSS5颜色规范目前正在起草中,这意味着还没有浏览器支持Color-contrast()
和Color-mix()
函数,它们的语法可能会发生变化。但它看起来确实是网络色彩的光明未来!
颜色的耗能影响
你知道在前端项目定义的颜色色板能影响网站的消耗吗?在OLED屏幕上(大多数现代电视和笔记本电脑都使用OLED),较暗的颜色比浅色使用的能量要少得多——白色使用的能量最多,黑色使用的能量最少。据《可持续网页设计》一书的作者汤姆·格林伍德(Tom Greenwood)说,在光谱中,蓝色比红色和绿色区域的颜色更耗能。为了减少应用程序对环境的影响,考虑更暗的颜色方案,使用更少的蓝色,或者为用户启用暗模式选项。此外,更环保的颜色选择还可以减少对移动设备电池寿命的影响。
原文地址:A Guide To Modern CSS Colors With RGB, HSL, HWB, LAB And LCH
原文作者:Michelle Barker
工具
- Hexplorer, Rob DiMarzo
Learn to understand hex colors with this interactive visualization. - LCH color picker, Lea Verou and Chris Lilley
Get LCH colors and their RGB counterparts. - HWB color picker
Visualize HWB colors and convert to HSL, RGB and hex. - Ally Color Tokens, Stephanie Eckles
An accessible color token generator.
相关链接
- “A Nerd’s Guide To Color On The Web,” Sarah Drasner, CSS-Tricks
- “LCH Colors In CSS: What, Why, And How?,” Lea Verou
- “The Best Color Functions In CSS?,” Chris Coyier, CSS-Tricks
- “Building A Color Scheme,” Adam Argyle, Web.dev
- “Using HSL Colors In CSS,” Ahmad Shaheed, Smashing Magazine
- “On Switching From Hex And RGB To HSL,” Sara Soueidan
- “Improving Color On The Web,” Dean Jackson, Webkit Blog