Skip to content

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 (亮度) 即可。

css
.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 图标、边框、阴影自动跟随文字颜色变化。

css
.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(...)仅背景色不影响 (文字依然清晰)。半透明遮罩层、玻璃特效背景。

错误示例: 想做一个半透明黑色背景,上面写白字。

css
/* ❌ 错误:文字也会变成半透明灰色,看不清 */
.box {
  background: black;
  opacity: 0.5; 
  color: white;
}

/* ✅ 正确:背景半透明,文字不透明 */
.box {
  background: rgba(0, 0, 0, 0.5);
  color: white;
}

5. 常见问题 (FAQ)

5.1 设计师给的颜色在我的屏幕上看起来不一样?

原因:

  1. 色域差异: 设计师可能用了 P3 色域(更鲜艳),而你的代码用了 sRGB (Hex/RGB),或者反之。

  2. 显示器校色: 硬件差异。

    解法: 尽量使用 Hex/RGB 这种标准 sRGB 格式开发,除非项目明确要求支持 P3 广色域(此时需使用 display-p3oklch)。

5.2 如何建立一套科学的颜色系统(主题切换)?

最佳实践: 使用 HSL + CSS 变量。 只定义色相(H)和饱和度(S),在不同组件中调整亮度(L)。

css
: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)。

css
background: linear-gradient(in oklch, red, blue); /* 颜色过渡非常鲜艳平滑 */

5.4 十六进制颜色 #f00#F00 有区别吗?

没有区别。CSS 颜色不区分大小写。通常推荐使用小写(易读性)或大写(由于复制粘贴自设计软件)。保持团队规范统一即可。

5.5 怎么从图片中提取颜色?

CSS 做不到。这需要 Canvas (JS) 或后端处理。 但 CSS 有一个取巧的属性 color-mix() (现代浏览器),可以混合颜色。

css
/* 混合 红色 和 白色,各占 50% -> 得到粉色 */
background: color-mix(in srgb, red, white);