CSS 颜色 (Colors)
在 CSS 中,颜色不仅仅是 #000000 那么简单。随着 CSS3 和 CSS4 的发展,我们有了更符合人类直觉的颜色模型(HSL)以及支持广色域屏幕的下一代颜色格式(LCH/OKLCH)。
1. 经典颜色格式
1.1 关键字 (Keywords)
CSS 预定义了 140 多种颜色名称。
- 常用:
red,blue,black,white. - 特殊:
transparent(全透明),currentColor(当前文本颜色). - 缺点: 难以微调,仅用于测试或黑白设置。
1.2 十六进制 (Hexadecimal)
最常用的格式,计算机友好。
- 6位:
#RRGGBB(如#ff0000红色). - 3位简写:
#RGB(如#f00等同于#ff0000). - 8位 (带透明度):
#RRGGBBAA. 最后两位代表 Alpha 通道 (00=透明, FF=不透明). - 例:
#00000080(半透明黑色).
1.3 RGB / RGBA
基于屏幕发光原理(红绿蓝)。
- 语法:
rgb(255, 0, 0)或rgba(255, 0, 0, 0.5). - 范围: 0-255.
- 现代写法 (CSS Level 4): 不再需要逗号,也不需要
a后缀。 rgb(255 0 0 / 50%)(推荐的新标准写法).
1.4 HSL / HSLA (推荐用于 UI 设计)
基于人类视觉直觉(色相、饱和度、亮度)。这是做 UI 只有一套配色方案时最强大的工具。
- 语法:
hsl(Hue, Saturation, Lightness, Alpha) - 参数详解:
- H (Hue 色相): 0-360 的色轮角度。0=红, 120=绿, 240=蓝.
- S (Saturation 饱和度): 0% (灰) ~ 100% (鲜艳).
- L (Lightness 亮度): 0% (黑) ~ 50% (纯色) ~ 100% (白).
- A: 透明度.
🔥 HSL 实战技巧: 做一个按钮的 hover 效果(变深或变亮),你不需要去查 RGB 数值,只需要调整 L (亮度) 即可。
.btn {
background: hsl(200, 100%, 50%); /* 纯亮蓝色 */
}
.btn:hover {
background: hsl(200, 100%, 40%); /* 只要把 L 减小,就是变暗 */
}2. 现代颜色格式 (CSS Color Level 4/5)
随着广色域屏幕(P3 屏、苹果视网膜屏)的普及,传统的 sRGB (Hex/RGB/HSL) 无法显示更鲜艳的颜色。
2.1 OKLCH (未来的主流)
OKLCH 是目前最完美的颜色空间,它解决了 HSL 在不同色相下视觉亮度不一致的问题(例如:HSL中纯黄和纯蓝的 L 都是 50%,但人眼觉得黄色亮得多)。
- 语法:
oklch(Lightness Chroma Hue)L: 0% - 100% (感知亮度).C: 0 - 0.4 (彩度/鲜艳度,支持超出 sRGB 范围).H: 0 - 360 (色相).
- 优势: 生成的渐变色极其平滑,不会出现中间发灰的情况。
3. 特殊颜色关键字
3.1 currentColor
这是一个“变量”,它自动指向当前元素(如果未指定,则继承父级)的 color 属性值。
场景: 让 SVG 图标、边框、阴影自动跟随文字颜色变化。
.button {
color: blue;
border: 1px solid currentColor; /* 边框也是蓝色 */
box-shadow: 0 0 5px currentColor; /* 阴影也是蓝色 */
}
.button:hover {
color: red; /* 此时边框和阴影自动变成红色,无需重写 */
}3.2 transparent
等同于 rgba(0,0,0,0)。常用于制作透明背景、三角形 hack。
4. opacity vs rgba/hsla (高频考点)
这是新手最容易混淆的概念。
| 属性 | 作用范围 | 子元素表现 | 场景 |
|---|---|---|---|
opacity: 0.5 | 整个元素 (包括背景、文字、边框、图片) | 继承透明度 (也会变淡,且无法通过 CSS 恢复)。 | 整个卡片淡出、禁用状态。 |
bg-color: rgba(...) | 仅背景色 | 不影响 (文字依然清晰)。 | 半透明遮罩层、玻璃特效背景。 |
错误示例: 想做一个半透明黑色背景,上面写白字。
/* ❌ 错误:文字也会变成半透明灰色,看不清 */
.box {
background: black;
opacity: 0.5;
color: white;
}
/* ✅ 正确:背景半透明,文字不透明 */
.box {
background: rgba(0, 0, 0, 0.5);
color: white;
}5. 常见问题 (FAQ)
5.1 设计师给的颜色在我的屏幕上看起来不一样?
原因:
色域差异: 设计师可能用了 P3 色域(更鲜艳),而你的代码用了 sRGB (Hex/RGB),或者反之。
显示器校色: 硬件差异。
解法: 尽量使用 Hex/RGB 这种标准 sRGB 格式开发,除非项目明确要求支持 P3 广色域(此时需使用
display-p3或oklch)。
5.2 如何建立一套科学的颜色系统(主题切换)?
最佳实践: 使用 HSL + CSS 变量。 只定义色相(H)和饱和度(S),在不同组件中调整亮度(L)。
:root {
/* 定义主色调:蓝色 */
--primary-h: 220;
--primary-s: 90%;
}
.btn-primary {
/* 基础色 */
background-color: hsl(var(--primary-h), var(--primary-s), 50%);
}
.btn-light {
/* 浅色变体 (只改亮度 L) */
background-color: hsl(var(--primary-h), var(--primary-s), 90%);
}
.dark-mode {
/* 暗黑模式只需改这一行,所有按钮自动变色 */
--primary-h: 220; /* 甚至可以换个色相 */
}5.3 为什么 linear-gradient(red, blue) 中间看起来脏脏的(发灰)?
原因: 在 sRGB 空间中插值,红变蓝的中间地带会经过灰色区域。 解法: 使用现代浏览器支持的颜色插值提示 (Color Interpolation)。
background: linear-gradient(in oklch, red, blue); /* 颜色过渡非常鲜艳平滑 */5.4 十六进制颜色 #f00 和 #F00 有区别吗?
没有区别。CSS 颜色不区分大小写。通常推荐使用小写(易读性)或大写(由于复制粘贴自设计软件)。保持团队规范统一即可。
5.5 怎么从图片中提取颜色?
CSS 做不到。这需要 Canvas (JS) 或后端处理。 但 CSS 有一个取巧的属性 color-mix() (现代浏览器),可以混合颜色。
/* 混合 红色 和 白色,各占 50% -> 得到粉色 */
background: color-mix(in srgb, red, white);