CSS 颜色值
要表示 CSS 中的颜色,必须找到一种方法将“颜色”的模拟概念转换为计算机可以使用的数字形式。这通常通过将颜色分解为组件来完成,例如不同原色的混合量,或亮度和色调。定义的颜色模型确保颜色无论在何处呈现都看起来相同。
颜色模型是使用数值表示颜色的数学模型。颜色模型描述如何在颜色空间内创建可用颜色。 RGB 是 web 的第一个颜色模型。sRGB
RGB 颜色模型的颜色空间(标准红、绿、蓝颜色空间)是在 1996 年为计算机显示器和 web 创建的。 颜色空间 是对颜色进行分组的系统,因此描述任何给定颜色都是一致的。如果您在两个不同的颜色空间之间转换颜色,它在两个空间中应该看起来都一样。
最初,显示器在可以呈现的颜色数量方面受到限制,CSS 颜色也受到这些限制,随着功能的改进而扩展。随着现代设备不再局限于 RGB,我们现在还拥有基于人类感知的颜色模型,提供了更广泛的 色域。我们现在可以通过几种方法在 CSS 中描述颜色,并且选项不断扩展。
本指南介绍了不同的 <color>
值类型。有关更详细的讨论,请参阅下面提供的参考链接。
关键词
web 定义了一组标准颜色名称,允许您使用关键字而不是数字表示来描述颜色。这是一种更简单但更有限的方法 - 可能没有关键字代表您想要使用的确切颜色。
颜色关键字包括标准的原色和二次色(例如 red
、blue
或 orange
),灰色阴影(从 black
到 white
,包括 darkgray
和 lightgrey
等颜色),以及各种其他混合色,包括 lightseagreen
、cornflowerblue
和 rebeccapurple
。命名颜色使用 RGB 模型,并与 sRGB (srgb
) 颜色空间相关联。
有超过 160 种命名颜色。有几种命名颜色特别受关注: transparent
设置透明颜色值,而 currentcolor
设置 CSS color
属性的当前值。还有一些命名的 <system-color>
颜色,例如 accentcolortext
和 buttonface
,它们反映了用户、浏览器或操作系统做出的默认颜色选择。
所有颜色关键字不区分大小写。有关颜色关键字的更多信息,请参阅 <named-color>
数据类型。
RGB 值
十六进制字符串表示法
十六进制(hex)字符串表示法使用十六进制值来表示 RGB 颜色每个分量(红、绿、蓝)。它可能还包括第四个分量:alpha 通道(或不透明度)。
十六进制字符串表示法中的颜色始终以字符 "#"
开头。之后是颜色代码的十六进制数字。字符串不区分大小写。
"#rrggbb"
-
指定一个完全不透明的颜色,其红色分量为十六进制数
0xrr
,绿色分量为0xgg
,蓝色分量为0xbb
。 "#rrggbbaa"
-
指定一个颜色,其红色分量为十六进制数
0xrr
,绿色分量为0xgg
,蓝色分量为0xbb
。alpha 通道由0xaa
指定;此值越低,颜色越透明。 "#rgb"
-
指定一个颜色,其红色分量为十六进制数
0xrr
,绿色分量为0xgg
,蓝色分量为0xbb
。 "#rgba"
-
指定一个颜色,其红色分量为十六进制数
0xrr
,绿色分量为0xgg
,蓝色分量为0xbb
。alpha 通道由0xaa
指定;此值越低,颜色越透明。
如上所示,红、绿、蓝颜色分量可以分别表示为双位十六进制值,表示介于 0 (00
) 和 255 (FF
) 之间的数字,或者单个十六进制值(介于 0 (0
) 和 15 (F
) 之间的数字)。
注意: 上述值中的前导 0x
表示十六进制整型字面量。十六进制整数可以包含数字 (0
- 9
) 和字母 a
– f
和 A
– F
。字符的大小写不影响其值。因此:0xa
= 0xA
= 10
和 0xf
= 0xF
= 15
。
这两个十六进制颜色是等效的颜色值;它们都是红色
color: #ff0000;
color: #f00;
所有分量**必须**使用相同数量的数字指定。如果使用单位数字表示法,则最终颜色通过将每个分量的数字重复使用两次来计算;也就是说,"#D"
在绘制时变为 "#DD"
。
要使值不透明度为 25%,请添加 alpha 通道值,如下所示
color: #ff000044;
color: #f004;
有关颜色的十六进制字符串表示法的更多信息,请参阅 <hex-color>
数据类型。
HTML 颜色输入类型
在许多情况下,您的网站可能需要让用户选择颜色。也许您有一个可自定义的用户界面,或者您正在实现一个绘图应用程序。也许您有可编辑的文本,需要让用户选择文本颜色。或者您的应用程序也许允许用户为文件夹或项目分配颜色。对于这些用例,<input>
元素有一个 "color"
type
,它会呈现一个颜色选择器控件。
此示例允许您选择颜色。一旦做出选择,border-color
将设置为该颜色,并将显示该值。
<div id="box">
<label for="colorPicker">Border color:</label>
<input type="color" value="#8888ff" id="colorPicker" />
<output></output>
</div>
HTML 创建一个包含颜色选择器控件的框(使用 <label>
元素创建标签)和一个空的 <output>
元素,我们将在其中使用 JavaScript 输出颜色的值。颜色输入的值始终是十六进制字符串。
以下 JavaScript 将边框的颜色更新为与颜色选择器的初始值匹配,然后在 <input type="color">
元素中添加两个事件处理程序以响应对它的值所做的更改。
const colorPicker = document.querySelector("#colorPicker");
const box = document.querySelector("#box");
const output = document.querySelector("output");
box.style.borderColor = colorPicker.value;
colorPicker.addEventListener(
"input",
(event) => {
box.style.borderColor = event.target.value;
},
false,
);
colorPicker.addEventListener(
"change",
(event) => {
output.innerText = `${colorPicker.value}`;
},
false,
);
每次元素的值更改时,都会发送 input
事件;也就是说,每次用户调整颜色选择器中的颜色时。每次此事件到达时,我们都将框的边框颜色设置为与颜色选择器的当前值匹配。
当颜色选择器的值最终确定时,将接收到 change
事件。我们通过将 <output>
的内容设置为所选颜色的字符串值来响应。
RGB 函数表示法
RGB(红/绿/蓝)函数表示法与十六进制字符串表示法类似,使用其红、绿、蓝分量(以及可选的不透明度的 alpha 通道分量)来表示颜色。但是,它不使用字符串,而是使用 CSS 函数 rgb()
来定义颜色。此函数接受 3 或 4 个输入参数 - 红、绿、蓝分量值和可选的 alpha 通道值。
这些参数中每一个的合法值是
red
、green
和blue
-
每个都必须是介于 0 和 255(含)之间的
<number>
值,介于 0% 和 100% 之间的<percentage>
,或者关键字none
,在本例中它等于0
。 alpha
-
alpha 通道指定为介于
0%
(完全透明)和100%
(完全不透明)之间的百分比,或者介于0.0
(等效于0%
)和1.0
(等效于100%
)之间的数字。
例如,不透明度为 50% 的亮红色可以表示为 rgb(255 0 0 / 50%)
或 rgb(100% 0 0 / 0.5)
。
有关 RGB 函数表示法的更多信息,请参阅 rgb()
颜色函数。
带色相组件的颜色函数
具有 <hue>
分量的颜色函数(来自该颜色模型的颜色轮的 <angle>
)包括 srgb
颜色函数 hsl()
和 hwb()
,CIElab 的 lch()
函数和 OKLab 的 oklch()
颜色函数。这些颜色函数更直观,因为色相使我们能够区分或识别红色、橙色、黄色、绿色、蓝色等颜色的差异或相似性。
HSL 函数表示法
hsl()
CSS 颜色函数是浏览器中第一个支持的基于色相的颜色函数。hsl()
比 rgb()
更直观 - 确定改变色相 (h
)、饱和度 (s
) 和亮度 (l
) 值的影响比通过红、绿、蓝通道值声明特定颜色更容易。此外,HSL 与 Photoshop 中的 HSB(色相、饱和度和亮度)颜色选择器类似,当第一次支持时,它立即为许多人所熟悉。
hsl()
和 hwb()
sRGB 颜色函数都是圆柱形的。色相将颜色定义为圆形颜色轮上的 <angle>
。下图显示了一个 HSL 颜色圆柱体。饱和度是一个百分比,它定义了颜色在完全灰度与具有给定色相的可能最大量之间尺度上的距离。随着亮度值增加,颜色从最暗过渡到最亮可能的颜色(从黑色到白色)。
图片由 Wikipedia 上的用户 SharkD 提供,根据 CC BY-SA 3.0 许可证发布。
HSL(或 HWB)颜色的色相 (H
) 分量的值是一个角度,从 0° 开始为红色,然后依次经过黄色、绿色、青色、蓝色和品红色,最后在 360° 处回到红色。该值可以使用 CSS 支持的任何 <angle>
单位指定,包括度数 (deg
)、弧度 (rad
)、梯度 (grad
) 或圈数 (turn
)。色相值识别颜色的基本色调,但它不控制颜色的鲜艳度或暗淡程度,也不控制颜色的明暗程度。
颜色的饱和度 (S
) 分量指定了最终颜色中包含的指定色相的百分比,其中 100% 表示完全饱和,0% 表示完全没有颜色(灰度)。亮度 (L
) 分量指定了颜色在完全黑色 (0%
) 和完全白色 (100%
) 之间滑动的尺度上的亮度。您还可以选择包含 alpha 通道,前面有一个斜杠 (/
) 以使颜色不透明度低于 100%。
以下是一些 HSL 表示法中的示例颜色
<table>
<thead>
<tr>
<th scope="col">Color in HSL notation</th>
<th scope="col">Example</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>hsl(90deg 0% 50%)</code></td>
<td style="background-color: hsl(90deg 0% 50%);"> </td>
</tr>
<tr>
<td><code>hsl(90 100% 50%)</code></td>
<td style="background-color: hsl(90 100% 50%);"> </td>
</tr>
<tr>
<td><code>hsl(0.15turn 50% 75%)</code></td>
<td style="background-color: hsl(0.15turn 50% 75%);"> </td>
</tr>
<tr>
<td><code>hsl(0.15turn 90% 75%)</code></td>
<td style="background-color: hsl(0.15turn 90% 75%);"> </td>
</tr>
<tr>
<td><code>hsl(0.15turn 90% 50%)</code></td>
<td style="background-color: hsl(0.15turn 90% 50%);"> </td>
</tr>
<tr>
<td><code>hsl(270deg 90% 50% / 50%)</code></td>
<td style="background-color: hsl(270deg 90% 50% / 50%);"> </td>
</tr>
</tbody>
</table>
最后一个值是不透明的;它包含可选的 alpha 值,前面有一个斜杠。
注意: 当您省略色相的单位时,它被假定为度数 (deg
)。
HWB 函数表示法
hwb()
颜色函数使用与 hsl()
相同的色相坐标系,其中 0deg
为红色。但是,hwb()
函数指定的是白度 (W
) 和黑度 (B
),而不是 hsl()
的亮度和饱和度。此函数也很直观 - 允许您选择色相,然后混合一定量的白色或黑色以实现所需的颜色。
W
和 B
值范围从 0%
到 100%
(或 0
到 1
)。如果 W
和 B
的组合值为 100%(或 1
)或更大,则颜色将为灰色,类似于将 hsl()
中的 s
设置为 0%
。与 hsl()
一样,也可以包含可选的 alpha 值,前面有一个斜杠 /
。
以下是一些使用 HWB 表示法的示例
/* These examples all specify varying shades of a lime green. */
hwb(90 10% 10%)
hwb(90 50% 10%)
hwb(90deg 10% 10%)
hwb(1.5708rad 60% 0%)
hwb(.25turn 0% 40%)
/* Same lime green but with an alpha value */
hwb(90 10% 10% / 0.5)
hwb(90 10% 10% / 50%)
在以下示例中,我们设置了与 hsl()
示例相同的色相,但我们通过 hwb()
而不是饱和度和亮度向每个色相添加了白度和黑度
<table>
<thead>
<tr>
<th scope="col">Color in HWB notation</th>
<th scope="col">Example</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>hwb(90deg 50% 50%)</code></td>
<td style="background-color: hwb(90deg 50% 50%);"> </td>
</tr>
<tr>
<td><code>hwb(90 0% 0%)</code></td>
<td style="background-color: hwb(90 0% 0%);"> </td>
</tr>
<tr>
<td><code>hwb(0.15turn 25% 0%)</code></td>
<td style="background-color: hwb(0.15turn 25% 0%);"> </td>
</tr>
<tr>
<td><code>hwb(0.15turn 10% 25%)</code></td>
<td style="background-color: hwb(0.15turn 10% 25%);"> </td>
</tr>
<tr>
<td><code>hwb(1turn 10% 65%)</code></td>
<td style="background-color: hwb(1turn 10% 65%);"> </td>
</tr>
<tr>
<td><code>hwb(270deg 75% 10%)</code></td>
<td style="background-color: hwb(270deg 75% 10%);"> </td>
</tr>
</tbody>
</table>
LCH 和 OKLCH:CIELAB 和 Oklab 颜色空间
虽然 hsl()
和 hwb()
很直观,但它们有一个主要缺点。使用这些函数,每个完全饱和的色相角 (hsl(<angle> 100% 50%)
或 hwb(<angle> 0% 0%)
) 都有相同的亮度,但人类的视觉或显示器并非如此。将白色文本放在完全饱和的蓝色 (hsl(240deg 100% 50%)
) 上是可以识别的,但将相同的文本放在完全饱和的黄色 (hsl(60deg 100% 50%)
) 上不仅无法识别,而且可能会伤害用户的眼睛。在这些颜色函数中,颜色的亮度是相对于其他颜色的,而不是相对于人类的感知。实际上,并非所有色相都具有相同的最大饱和度。
如果您可以简单地更改网站上颜色的色相通道,而不会使文本无法识别,那不是很好吗?使用 CIELAB 和 Oklab 颜色空间中的颜色函数就可以做到。
CIELAB 和 Oklab 颜色空间表示人类可以看见的全部颜色范围。CIE lab 颜色函数包括 lch()
和 lab()
。Oklab 颜色函数包括 oklch()
和 oklab()
。这些模型的主要目的是,它们是统一的,因此颜色空间中任意两点之间的给定距离应该在观察者眼中显得同样不同。Oklab 是一个使用与 CIELAB 相同模型类型的颜色空间,但它是在额外的数值优化步骤的基础上构建的,因此其值被认为比 CIELAB 更准确。由于这种优化,色相在感知上更均匀。
lch()
和 oklch()
函数使用亮度 (L
)、色度 (C
) 和色相 (H
),在本节中将进一步讨论。lab()
和 oklab()
函数的工作方式不同,它们使用亮度 (L
)、红/绿度 (沿 a
轴) 和黄/蓝度 (沿 b
轴)。这些轴被称为矩形坐标。这些颜色函数的主要优势是“亮度”是感知亮度;它是人眼感知的颜色亮度,而不是相对于其他颜色的亮度。
与 sRGB 色调颜色函数类似,lch()
和 oklch()
中的色调 (h
) 值是一个数字、一个角度或关键字 none
(等效于 0deg
),表示颜色的 <hue>
角。但是,每个角度值的颜色并不相同。与特定色调相对应的角度在 sRGB、CIELAB(lch()
使用)和 Oklab(oklch()
使用)颜色空间中有所不同。
以下渐变演示了 sRGB、CIE Lab 和 OKlab 颜色空间中从 0deg
到 360deg
的每个角度的色调颜色。
您可能会注意到,与 sRGB 渐变相比,后者的渐变在整个色调光谱中的亮度更加均匀。选择上面示例中的复选框,将色调渐变转换为灰度,以更明显地显示这一点。
还要注意,CIE Lab 中的蓝色值的分布比其他两个颜色空间中的蓝色值更长。这就是 lch()
和 oklch()
之间的区别。lch()
蓝色值的分布是由于一个错误,导致 270deg
和 330deg
之间的色调值的色度和亮度发生了偏移。这个问题在 oklab 颜色空间中得到了解决,因此 oklch()
颜色表示法也得以解决。
如上所述,lch()
和 oklch()
中的色调 (H
) 是一个 <angle>
、number
或关键字 none
。lightness
可以是 <percentage>
,对于 lch()
,可以是 0
到 100
之间的数字,对于 oklch()
,可以是 0
到 1
之间的数字,其中 0
或 0%
表示完全没有亮度,也就是黑色。
C
是一个 <number>
、<percentage>
或关键字 none
(等效于 0%
),表示颜色的色度或“颜色量”。这类似于 hsl()
颜色函数的 S
饱和度值。值 0
表示完全没有色度或饱和度;导致灰色,介于白色和黑色之间,具体取决于亮度值。数字值理论上是无界的,100%
等于 lch()
的 150
和 oklch()
的 0.4
。
与其他颜色函数一样,还有一个可选的 alpha 透明度值,前面是斜杠 (/
)。
下面的示例显示了在 lch()
和 oklch()
函数中更改亮度值的效果。
Lab 和 OKLab
lab()
函数表示法以 CIE L*a*b* 颜色空间表示给定的颜色。oklab()
函数在 OKLab 颜色空间中定义颜色。这些函数通过指定颜色的亮度 (L
)、红绿轴值 (a
)、蓝黄轴值 (b
) 以及可选的 alpha 透明度值,表示人类可以看到的全部颜色范围。
与 lch()
和 oklch()
类似,lightness
可以是
<percentage>
,其中0%
表示完全黑色,100%
表示完全白色。- 对于
lab()
,可以是0
到100
之间的数字,对于oklab()
,可以是0
到1
之间的数字,其中0
表示完全黑色,1
/100
表示完全白色。
a
值是 <number>
,对于 lab()
,可以是 -125
到 125
之间,对于 oklab()
,可以是 -0.4
到 0.4
之间,<percentage>
可以是 -100%
到 100%
之间,或者关键字 none
(在本例中等效于 0%
)。此值指定颜色在颜色空间中的 a 轴上的距离,定义了颜色是偏绿(向 -100% 移动)还是偏红(向 +100% 移动)。
请注意,这些值是有符号的(允许正值和负值),理论上是无界的,这意味着您可以设置超过 ±125 或 ±0.4 (±100%) 限制的值。实际上,值不能超过 ±160 或 ±0.5,分别。
b
值具有相同的约束条件。它指定颜色在颜色空间中的 b 轴上的距离,定义了颜色是偏蓝(向 -100% 移动)还是偏黄(向 +100% 移动)。
以下示例演示了通过 lab()
函数改变 a
轴和通过 oklab()
函数改变 b
轴的效果。
其他颜色函数表示法
color()
函数
如果您希望在定义颜色时显式控制颜色空间,可以使用 color()
函数。
这对于描述具有更宽颜色 色域 的高清设备的颜色很有用。例如,如果您想显示 display-p3 0 0 1
颜色,该颜色超出了 sRGB 色域,可以使用 @media
color-gamut
at-rule 在尝试使用它之前检测客户端硬件是否支持此范围内的颜色。
.vibrant {
background-color: color(srgb 0 0 1);
}
@media (color-gamut: p3) {
.vibrant {
background-color: color(display-p3 0 0 1);
/* Equivalent to out-of-gamut color(srgb 0 0 1.042) */
}
}
在讨论相对颜色时,理解 color()
非常重要。上面讨论的旧的 sRGB 颜色表示法(hsl()
、hwb()
和 rgb()
)不能表达可见颜色的全部光谱,而 color()
函数支持更宽的颜色色域。因此,当使用旧的函数类型定义相对颜色时,查询 HTMLElement.style
属性或 CSSStyleDeclaration.getPropertyValue()
方法返回的输出颜色将是 color(srgb ...)
值。
要查看将 hsl()
、hwb()
和 rgb()
颜色函数转换为 srgb
颜色空间中的 color()
的示例,请查看我们的 颜色选择器工具。
相对颜色
color-mix()
函数
color-mix()
函数接受上面提到的任何语法的两个颜色值,每个颜色可选地带比例百分比值,并返回在给定颜色空间中以给定量混合它们的结果。
light-dark()
函数
light-dark()
函数允许您为打算在浅色和深色配色方案中使用的属性指定两个颜色值。哪个值被设置取决于开发人员是否设置了浅色或深色配色方案,或者用户是否请求了浅色或深色配色方案。这是一个快捷函数,允许您实现与 prefers-color-scheme
媒体功能查询相同的结果,但代码更少。