CSS 颜色值
要在 CSS 中表示一种颜色,你必须找到一种方法,将“颜色”这个模拟概念转换为计算机可以使用的数字形式。这通常是通过将颜色分解为其组成部分来完成的,例如混合不同原色的量,或者亮度和色相。已定义的颜色模型可确保无论颜色在何处渲染,其显示效果都相同。
颜色模型是一种使用数值来表示颜色的数学模型。颜色模型描述了如何在色彩空间内创建可用的颜色。RGB 是 Web 的第一个颜色模型。RGB 颜色模型的 sRGB 色彩空间(即标准的红、绿、蓝色彩空间)创建于 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 值
在 CSS 中,主要有两种方法通过其红、绿、蓝分量来定义 RGB 颜色——十六进制值和 rgb() 值。与命名颜色一样,这些方法使用 RGB 模型,并与 sRGB(srgb)色彩空间相关联。但是,它们允许指定更广泛的颜色范围。
十六进制字符串表示法
十六进制(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;
});
colorPicker.addEventListener("change", (event) => {
output.innerText = `${colorPicker.value}`;
});
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 颜色圆柱体。饱和度是一个百分比,定义了颜色在完全灰度到具有给定色相最大可能量的范围内的位置。随着亮度值的增加,颜色从最暗的颜色过渡到最亮的可能颜色(从黑色到白色)。

图片由 维基百科用户 SharkD 提供,根据 CC BY-SA 3.0 许可证分发。
HSL(或 HWB)颜色的色相(H)分量的值是一个角度,从 0° 的红色开始,然后经过黄色、绿色、青色、蓝色和品红色,最后在 360° 再次回到红色。该值可以用 CSS 支持的任何<angle>单位指定,包括度(deg)、弧度(rad)、百分度(grad)或圈(turn)。色相值标识了颜色的基本色调,但它不控制颜色的鲜艳度或暗淡度,也不控制颜色的明暗。
颜色的饱和度(S)分量指定最终颜色中指定色相所占的百分比,其中 100% 为完全饱和,0% 为完全没有颜色(灰度)。亮度(L)分量指定颜色在完全黑色(0%)和完全白色(100%)之间的滑动刻度上的明亮程度。你还可以选择性地包含一个 alpha 通道,前面加上斜杠(/),使颜色不完全不透明。
以下是一些 HSL 表示法的示例颜色
最后一个值是半透明的;它包含了可选的 alpha 值,前面有一个正斜杠。
备注: 当你省略色相的单位时,它被假定为度(deg)。
HWB 函数表示法
hwb() 颜色函数使用与 hsl() 相同的色相坐标系,其中 0deg 是红色。然而,hwb() 函数不是使用 hsl() 的亮度和饱和度,而是指定白度(W)和黑度(B)。这个函数也相当直观——允许你选择一个色相,然后混入一定量的白色和/或黑色以达到所需的颜色。
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() 为每个色相添加了白度和黑度,而不是饱和度和亮度
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() 的蓝色分布是由于一个 bug,它会改变 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 值是一个介于 -125 和 125 之间的 <number>(对于 lab())或介于 -0.4 和 0.4 之间的 <number>(对于 oklab()),一个介于 -100% 和 100% 之间的 <percentage>,或者是关键字 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 ...) 值。
相对颜色
上面列出的每个颜色函数都可以用来定义相对颜色,它允许<color>值相对于其他现有颜色进行定义,而不是每次都从头定义一个颜色值。这个强大的功能能够创建现有颜色的补充色——例如原始颜色的更亮、更暗、饱和、半透明或反色的变体。相对颜色提供了一种创建调色板和定义颜色调整的有效机制。请参阅每个颜色函数的页面以了解其相对语法的更多信息。
如上所述,当使用 rgb()、hsl() 或 hwb() 输出相对颜色时,输出的颜色将是 srgb 色彩空间中的一个 color() 函数。
color-mix() 函数
color-mix() 函数接受两个任意语法的颜色值,可选择为每种颜色指定比例百分比值,并返回在给定色彩空间中按给定数量混合它们的结果。
light-dark() 函数
light-dark() 函数允许你为一个属性指定两个颜色值,分别用于浅色和深色方案。设置哪个值取决于开发者是否设置或用户是否请求了浅色或深色方案。这是一个快捷函数,允许你用更少的代码实现与 prefers-color-scheme 媒体特性查询相同的结果。