当前内容所在位置(可进入专栏查看其他译好的章节内容)
- 第四部分 视觉增强技术 ✔️
- 【第 11 章 颜色与对比】 ✔️
- 11.1 通过对比进行交流
- 11.1.1 模式的建立
- 11.1.2 还原设计稿
- 11.2 颜色的定义
- 11.2.1 色域与色彩空间
- 11.2.2 CSS 颜色表示法 ✔️
- 11.2.2.1 RGB 与 十六进制颜色 ✔️
- 11.2.2.2 HSL 颜色表示法 ✔️
- 11.2.2.3 HWB 颜色表示法 ✔️
- 11.2.2.4 新一代色彩空间 ✔️
- 11.2.2.5 LAB 和 OKLAB 颜色表示法 ✔️
- 11.2.2.6 LCH 和 OKLCH 颜色表示法 ✔️
文章目录
- 11.2.2 CSS 颜色表示法 CSS color notations
- 11.2.2.1 RGB 与十六进制颜色表示法 RGB and hex color
- 11.2.2.2 HSL 颜色表示法 HSL color
- 11.2.2.3 HWB 颜色表示法 HWB color
- 11.2.2.4 新一代色彩空间 Next-generation color spaces
- 11.2.2.5 LAB 和 OKLAB 颜色表示法 LAB and OKLAB color
- 11.2.2.6 LCH 和 OKLCH 颜色表示法 LCH and OKLCH color
《CSS in Depth》新版封面
译者按
再次怀着无比敬畏之心完成本小节的翻译。本篇几乎完全重写了上一版中的同名章节内容,将 CSS 近年来在颜色描述方面的重大进展及相关背景情况都一一进行了介绍。虽然每个部分的篇幅并不长,但硬核知识点是一个都不少。即便是亲自翻译了一遍,个别知识点的理解还远远不够,需要另抽时间不断强化。一起来看看吧。
11.2.2 CSS 颜色表示法 CSS color notations
CSS 目前支持多种颜色表示方法,包括 rgb()
表示法和 hsl()
函数表示法等。这些函数在各种浏览器中都得到了很好的支持。
另外还有一些新的表示法尚未得到很好的支持,例如 hwb()
、lab()
、lch()
、oklab()
、oklch()
等等。这些颜色表示方法也是直到 2022 年末至 2023 年 6 月前后才陆续添加到浏览器中。截止到 2024 年 6 月前后,启用这些颜色表示法可能还需要定义回退值才妥当;不过随着浏览器的逐步升级,这些新的表示法也将逐渐推广普及。想了解最新的浏览器兼容情况,可以查看 Can I Use 网站发布的最新数据:https://mng.bz/EZKo。
译注:OKLCH 的浏览器最新兼容情况
以下为截至 2024 年 12 月 6 日 OKLCH 颜色表示法在各种浏览器上的兼容情况截图。可以看到目前 OKLCH 已经得到了各大主流浏览器的全面支持,综合支持率也已高达 92.19%。是时候深入解析这一全新的颜色描述方式了。
【补图:OKLCH 颜色体系当前的浏览器支持情况一览表,已全面获得各主流浏览器支持(截至 2024 年 12 月 6 日)】
上面提到的每一种表示方法都对应一个特定的色彩空间,它们整体为 CSS 的颜色管理提供了海量的选择。接下来我将简要介绍每种表示法的工作原理以及它们之间的相互关系。然后会从中选取几种表示法进行对比演示。
我最偏好的表示法是 hsl()
—— 这也是浏览器目前兼容性最好的颜色表示方法了。此外还有 oklch()
表示法 —— 一种最为直观(intuitive)的颜色表示法。相信在不久的将来,一旦得到浏览器的普遍支持,oklch()
必将成为我新的首选表示法。
11.2.2.1 RGB 与十六进制颜色表示法 RGB and hex color
十六进制颜色表示法分别规定了红、绿、蓝三原色的取值,且每种颜色分量都用两位数的十六进制数值来表示,取值范围介于 00
到 FF
之间。十六进制是一种以 16 为基数的数字系统,十到十五的数值分别用字母 A
到 F
表示。例如颜色 #80c090
表示红色 80
、绿色 c0
、蓝色 90
(相当于十进制下的红色 128
、绿色 192
和蓝色 144
)。
新版的八位十六进制表示法还包括了另外两位数,用于表示 α 通道(alpha channel) 值,即透明度的大小。该值的取值范围同样介于 00
(即完全透明)到 FF
(即完全不透明)。因此,#80c09088
其实是颜色值 #80c090
的半透明版本。
注意
十六进制表示法有时也可以简写为三位数,其中每位数字都各重复一次(doubled)。例如,
#c90
等效于#cc9900
。此外还有一种对应的四位数表示,可以通过类似处理扩展为带α
值的八位十六进制颜色值。
而 rgb()
函数则是一种使用十进制数而非十六进制数来描述颜色的方法。其各颜色分量的取值范围不再是十六进制下的 00
到 FF
,而是对应的 0
到 255
。例如 rgb(0 0 0)
表示纯黑色(等效于 #000
);rgb(136 0 0)
则表示砖红色(等效于 #800
)。
RGB
与十六进制表示法仅适用于 sRGB
色域标准。无论是 RGB 表示法还是十六进制表示法,理解起来都有点费劲。我们见到一个颜色值,例如 #2097c9
,或者它对应的 RGB 颜色,无法联想到它在页面会渲染成什么样。如果尝试分解一下,它的红色值(20
)将非常少,绿色值(97
)为中等水平,蓝色值(c9
)则相对偏高。经分析得出,该颜色的蓝色和绿色占主导,但是颜色有多深呢?又有多鲜艳呢?都说不准。事实上,RGB 颜色表示法很不直观,它们本来就是方便计算机读取的,并不适合用肉眼识别。
十六进制颜色表示法只有当需要某种书写简洁、且可以方便地在不同应用程序之间复制粘贴颜色值时才有一席用武之地;而 RGB 表示法同样问题多多,和十六进制法相比妥妥的令人费解有余而方便简洁不足。然而其他大部分颜色表示法都比它们更加好懂且易用。
11.2.2.2 HSL 颜色表示法 HSL color
HSL 则是一种更适合人类读取的颜色表示法,其名称分别代表色调(Hue)、饱和度(Saturation)和亮度(Lightness)。HSL 的语法形如 hsl(198deg 73% 46%)
,相当于十六进制下的 #2097c9
。
在 HSL 中,代表色调的第一个参数其实是一个角度值,取值范围介于 0 度到 359 度之间。它代表色相环 1 上的度数,可以从红色(red,0度)依次过渡到黄色(yellow,60度)、绿色(green,120度)、青色(cyan,180度)、蓝色(blue,240度)、洋红色(magenta,300度),然后再回到红色。此外,角度取值范围以外的值仍然是有效的,并可通过加减 360 度来找到等效的色相环上的色调值。书写时也可以省略角度单位 deg
,直接写成一个数字。
HSL 表示法的第二个参数代表饱和度,是一个代表颜色强度的百分数:值为 100%
时颜色最鲜艳;为 0%
则意味着没有彩色,仅呈现一片灰色。
HSL 表示法的第三个参数表示亮度。它也是百分数,用以描述颜色的明暗程度。大部分鲜艳的颜色采用的是 50%
的亮度值,且亮度值越高,颜色越浅,浅至 100%
时就变成了纯白色;而当亮度值越低,颜色越深,深至 0%
就变成了黑色。
再比如,hsl(198deg 73% 46%)
这个颜色值,其色调为青蓝色,饱和度相当高(73%
),而亮度接近 50%
,因此会产生一个比天蓝色更深一些的蓝色。HSL 颜色表示法也只适用于 sRGB
色域标准。
提示:一种更新的、不使用逗号的颜色函数表示法
在 CSS 首次引入 RGB 表示法和 HSL 表示法时,
rgb()
和hsl()
颜色函数在使用时必须用逗号分隔每个参数,不能写作rgb(136 0 0)
,而必须写作rgb(136, 0, 0)
。为了向下兼容,这些颜色函数继续保留用逗号分隔的写法;而对于其他新推出的颜色函数就只支持不带逗号的写法。因此推荐使用无逗号写法,这样所有浏览器都支持该语法。
rgb()
和hsl()
也有相应的rgba()
版本和hsla()
版本,这些扩展函数可以接受第四个参数来设置代表颜色透明度的 alpha 通道值。现在已经不用再写这些扩展函数了,因为新版语法也支持写在斜线后的alpha
参数设置。例如,rgb(136 0 0 / 0.7)
定义了一个 不透明度 为70%
的砖红色(brick red)。后续介绍的所有颜色函数都支持通过这种方式设置的不透明度。
11.2.2.3 HWB 颜色表示法 HWB color
HWB 表示色调(Hue)、白度(Whiteness)和黑度(Blackness)。例如,某颜色利用该表示法可以写作 hwb(198deg 12.5% 20.4%)
。它其实等效于之前介绍过的用 HSL 表示法描述的那个深蓝色。
HWB 颜色表示法中的色调值等同于 HSL 表示法中的色调值;同样,它既可以写成一个角度值,也可以直接写成一个数字。
HWB 表示法中的 W 值和 B 值均为百分数,分别用于描述该颜色混入了多少白色或黑色。如果两个值都偏低,那么最终颜色就会更鲜艳。hwb(0deg 100% 0%)
即为纯白色(此时的颜色与色调无关);而 hwb(0deg 0% 100%)
则为纯黑色;如果 W 和 B 之和大于或等于 100%
,则最终颜色将为纯灰色,其深浅程度取决于二者中取值更大的一方。HWB 表示法同样仅适用于 sRGB
色域标准。
11.2.2.4 新一代色彩空间 Next-generation color spaces
接下来的四种颜色表示法适用于 广色域色彩空间(wide gamut color spaces)。这些表示方法不局限于 sRGB
色域或其他任何色域,而是能够代表人眼所能看到的任何颜色。换句话说,它们甚至可以描述超出硬件能力边界的颜色。在这种情况下,浏览器会自动将这些颜色做圆整处理,并归入最接近的可用色域范围内——只要不超出预期的取值范围,通常就能得到可接受的备选颜色。比如,可以利用这个原理来指定 P3 色域下的颜色,对于不支持 P3 色域的显示器而言,用户最终看到的将是最接近该颜色的 sRGB
色域下的近似值。
这些颜色表示法的另一个好处在于,它们力求在色彩感知上做到线性展示。也就是说,其颜色值是根据我们人类的感知来定制的。例如,在 HSL 体系中,亮度为 50%
的绿色会比同等亮度下的蓝色看起来更亮一些,因为我们的眼睛会认为绿色更亮;而在新一代色彩空间中,色彩是均衡的(balanced),因此相同亮度的所有色调对我们的眼睛而言都是一样的。同理,在控制色彩鲜艳度的数值上也是如此。
LAB 和 LCH 是其中最先创建的两种颜色表示法,但它们的规范尤其是在一些蓝色和紫色的色调方面还存在一些与规范不一致的地方,因此其表现也差强人意。后来 OKLAB 和 OKLCH 表示法取代了它们。新方法在概念上类似,但行为上可预测性更强。虽然接下来我将分别介绍这四种颜色表示法的工作原理,但还是强烈推荐使用 OKLAB 和 OKLCH 表示法。浏览器对以上四种表示法的支持情况也几乎完全相同。
11.2.2.5 LAB 和 OKLAB 颜色表示法 LAB and OKLAB color
LAB 颜色及其后续版本 OKLAB 都定义了三个维度值:亮度、A 轴(A axis)与 B 轴(B axis)。其语法格式形如 lab(58% -19 -35)
或者 oklab(65% -0.06 -0.1)
。虽然二者的数值不同,但在概念上都是相同的。
第一个参数,亮度,是一个值域介于 0%
(即黑色)到 100%
(白色)的百分数。在 LAB 表示法中,也可以使用 0 到 100 间的数字来表示;而在 OKLAB 中,还可以写成 0 到 1.0 之间的数字。鉴于这种写法上的差异可能引起混淆,推荐还是使用百分数为上。
而 A 轴的取值范围介于红色到绿色;B 轴则介于蓝色到黄色。在 OKLAB 中,这些值的具体范围分别是 -0.4
到 0.4
(也可以使用 -100%
到 100%
之间的百分数来表示)。而在 LAB 中,上述值的值域则为 -125
到 125
。
LAB 和 OKLAB 都是矩形色彩空间,类似于 RGB 的广色域版本;但与 RGB 类似,它们使用起来都不是很直观。
11.2.2.6 LCH 和 OKLCH 颜色表示法 LCH and OKLCH color
LCH 和 OKLCH 则是与 HSL 相似的圆柱形色彩空间(cylindrical color spaces)。它们定义的是这三个维度值:亮度(Lightness)、色度(Chroma)和色调(Hue),语法上则可以写作 lch(58% 39.8 241.5deg)
以及 oklch(64% 0.12 233deg)
。
提示
OKLCH 这个名字有点拗口。Web 开发者 埃里克·波蒂斯(Eric Portis) 首创了 “Oklachroma” 这个词来作为 OKLCH 的一种更为友好的发音方式,别说还挺好记的。
第一个参数定义了感知到的亮度。它也是一个介于 0%
(即黑色)到 100%
(即白色)的百分数,也可以写成 0
到 1.0
的十进制形式,与 HSL 中的亮度定义非常类似,但 LCH 和 OKLCH 在不同的色调表现中更加一致,更符合我们人眼的感知。
第二个参数色度值(chroma value)表示色彩的鲜艳程度。色度值为 0
则表示纯灰色,这与 HSL 中的饱和度也十分类似。从理论上讲,该参数值是没有范围限制的;但在实际应用中,OKLCH 色度的取值往往不超过 0.5
(在 sRGB
色域中也不会超过 0.33
)。而在 LCH 中,色度的取值范围则是 0
到 230
。
最后一个参数是色调(hue)。它也是色相环上的某个角度值,类似 HSL 中的色调概念,只是具体数值重新做了调整。其取值范围为:从红色(red,30)依次过渡到黄色(yellow,90)、绿色(green,140)、青色(cyan,195)、蓝色(blue,260)、洋红色(magenta,330),最后又回到红色。
利用 color() 函数在更宽的色域中使用 RGB 颜色
CSS 提供了一个
color()
函数,可以用来手动设置色域及颜色值。例如,color(display-p3 0.3 0.59 0.77)
可以对P3
色域下的红色、绿色、蓝色分别进行定义。该颜色值等效于oklch(64% 0.12 233deg)
。个人认为在通常情况下,该颜色表示法不如前面介绍的几种实用,因为它采用的是一种基于 RGB 的范式(RGB-based paradigm),写起来也比较冗长。由于 OKLAB 和 OKLCH 等广色域表示法可以描述肉眼可见光谱中的任何颜色,因此,如若将来显示器升级到支持更广的色域标准,它们仍然可以胜任各种色彩的展示。
不过,
color()
函数除了支持sRGB
、Display p3
和Rec2020
色域外,还支持更多冷僻色域,因此如果需要在特定色域内定义颜色,color()
函数应该会非常有用。想了解更多color()
函数的相关信息,可以参考 MDN 的在线文档:https://mng.bz/lMQ6。
总结一下,以上介绍的每种颜色表示法都是由以下参数分别定义的:
- RGB —— 红、绿、蓝(值域均为
0
到255
) - HSL —— 色调(角度值)、饱和度(百分数)、亮度(百分数)
- HWB —— 色调(角度值)、白度(百分数)、黑度(百分数)
- LAB —— 亮度(百分数),A 轴(
-125
红色至125
绿色),B 轴(-125
蓝色至125
黄色) - OKLAB —— 亮度(百分数),A 轴(
-0.4
红色至0.4
绿色),B 轴(-0.4
蓝色至0.4
黄色) - LCH —— 亮度(百分数)、色度(值域
0
到230
)、色调(角度值) - OKLCH —— 亮度(百分数)、色度(值域
0
到0.5
)、色调(角度值)
上述表示方法中,大部分还支持 none
关键字来代替其中的某个参数,用于表示该参数无关紧要。例如,oklch(100% 0 0deg)
表示白色,因此色调的取值基本上没有意义。这时就可以写作 oklch(100% 0 none)
甚至是 oklch(100% none none)
。
图 11.12 对比展示了几种典型颜色在指定的几种色彩空间中的不同表示方法。对于其中个别数值做了些微调。
【图 11.12 等效颜色值对比图】
以上这些特定的颜色也可以通过引用它们的合法名称来进行声明(如 blue
、lavender
、lightgray
等)。CSS 中大约有 150 种类似的合法命名颜色(named colors)。有关命名颜色的完整列表,详见 MDN 官方文档 <named-color>
:https://mng.bz/NRoN。
想要熟悉 OKLCH 或者其他任何色彩空间,最好的方法莫过于付诸实践。下一节我将深入介绍 OKLCH 在页面颜色配置中的具体用法,并推荐几个在使用过程中挺有帮助的实用工具。
关于《CSS in Depth》(中译本书名《深入解析 CSS》)
第 1 版 | 第 2 版 | |
---|---|---|
读者评分 | 原版:4.7(亚马逊);中文版:9.3(豆瓣) | 原版:5.0(亚马逊);中文版:暂无,待出版 |
出版时间 | 原版:2018 年 3 月;中文版:2020 年 4 月 | 原版:2024 年 7 月;中文版:暂无,待出版 |
原价 | 原版:$44.99;中文版:¥139.00 | 原版:$59.99;中文版:暂无,待出版 |
现价 | 原版:$36.49;中文版:¥52.54 起步 | 原版:$52.09;中文版:暂无,待出版 |
原版国内预订 | 起步价 ¥461.00 | 起步价 ¥750.00 |
本专栏为该书第 2 版高分译文专栏,全网首发,精译精校,持续更新,计划今年内完成全书翻译,敬请期待!!!
目前已完结的章节(可进入本专栏查看详情,连载期间完全免费):
- 第一章 层叠、优先级与继承(已完结)
- 1.1 层叠
- 1.2 继承
- 1.3 特殊值
- 1.4 简写属性
- 1.5 CSS 渐进式增强技术
- 1.6 本章小结
- 第二章 相对单位(已完结)
- 2.1 相对单位的威力
- 2.2 em 与 rem
- 2.3 告别像素思维
- 2.4 视口的相对单位
- 2.5 无单位的数值与行高
- 2.6 自定义属性
- 2.7 本章小结
- 第三章 文档流与盒模型(已完结)
- 3.1 常规文档流
- 3.2 盒模型
- 3.3 元素的高度
- 3.4 负的外边距
- 3.5 外边距折叠
- 3.6 容器内的元素间距问题
- 3.7 本章小结
- 第四章 Flexbox 布局(已完结)
- 4.1 Flexbox 布局原理
- 4.2 弹性子元素的大小
- 4.3 弹性布局的方向
- 4.4 对齐、间距等细节处
- 4.5 本章小结
- 第五章 网格布局(已完结)
- 5.1 构建基础网格
- 5.2 网格结构剖析 (上)
- 5.2.1 网格线的编号(下)
- 5.2.2 网格与 Flexbox 配合(下)
- 5.3 两种替代语法
- 5.3.1 命名网格线
- 5.3.2 命名网格区域
- 5.4 显式网格与隐式网格(上)
- 5.4.1 添加变化 (中)
- 5.4.2 让网格元素填满网格轨道(下)
- 5.5 子网格(全新增补内容)
- 5.6 对齐相关的属性
- 5.7 本章小结
- 第六章 定位与堆叠上下文(已完结)
- 6.1 固定定位
- 6.1.1 创建一个固定定位的模态对话框
- 6.1.2 在模态对话框打开时防止屏幕滚动
- 6.1.3 控制定位元素的大小
- 6.2 绝对定位
- 6.2.1 关闭按钮的绝对定位
- 6.2.2 伪元素的定位问题
- 6.3 相对定位
- 6.3.1 创建下拉菜单(上)
- 6.3.2 创建 CSS 三角形(下)
- 6.4 堆叠上下文与 z-index
- 6.4.1 理解渲染过程与堆叠顺序(上)
- 6.4.2 用 z-index 控制堆叠顺序(上)
- 6.4.3 深入理解堆叠上下文(下)
- 6.5 粘性定位
- 6.6 本章小结
- 第七章 响应式设计(已完结)
- 7.1 移动端优先设计原则(上篇)
- 7.1.1 创建移动端菜单(下篇)
- 7.1.2 给视口添加 meta 标签(下篇)
- 7.2 媒体查询(上篇)
- 7.2.1 深入理解媒体查询的类型(上篇)
- 7.2.2 页面断点的添加(中篇)
- 7.2.3 响应式列的添加(下篇)
- 7.3 流式布局
- 7.4 响应式图片
- 7.5 本章小结
- 第八章 层叠图层及其嵌套
- 8.1 用 layer 图层来操控层叠规则(上篇)
- 8.1.1 图层的定义(上篇)
- 8.1.2 图层的顺序与优先级(下篇)
- 8.1.3 revert-layer 关键字(下篇)
- 8.2 层叠图层的推荐组织方案
- 8.3 伪类 :is() 和 :where() 的用法
- 8.4 CSS 嵌套的使用
- 8.4.1 嵌套选择器的使用
- 8.4.2 深入理解嵌套选择器
- 8.4.3 媒体查询及其他 @规则 的嵌套
- 8.5 本章小结
- 第九章 CSS 的模块化与作用域
- 9.1 模块的定义
- 9.1.1 模块和全局样式
- 9.1.2 一个简单的 CSS 模块
- 9.1.3 模块的变体
- 9.1.4 多元素模块
- 9.2 将模块组合为更大的结构
- 9.2.1 模块中多个职责的拆分
- 9.2.2 模块的命名
- 9.3 CSS 的作用域
- 9.3.1 CSS 作用域的就近原则
- 9.3.2 划定作用域的边界
- 9.3.3 CSS 中的隐式作用域
- 9.3.4 关于 CSS 作用域与层叠图层
- 9.4 CSS 模式库
- 9.5 本章小结
- 第十章 CSS 容器查询
- 10.1 容器查询的一个简单示例
- 10.1.1 容器尺寸查询的用法
- 10.2 深入理解容器
- 10.2.1 容器的类型
- 10.2.2 容器的名称
- 10.2.3 容器与模块化 CSS
- 10.3 与容器相关的单位
- 10.4 容器样式查询的用法
- 10.4.1 将模块与所在容器解耦
- 10.4.2 减少重复代码
- 10.5 本章小结
- 附录
- 附录A:CSS 选择器参考
- 附录B:CSS 预处理器简介
色相环(Hue Circle)是一个用于表示颜色关系的圆形图表,通常用于视觉艺术、设计和色彩理论中。色相环展示了颜色之间的相对位置和过渡,帮助理解色彩的组合和对比。 ↩︎