CSS Handbook · 颜色与视觉效果

第七章 / 7.1 颜色系统与透明度

第七章 · 7.1 节

颜色系统与透明度


CSS 提供了不止一种描述颜色的方式,从最原始的十六进制色值,到贴近设计师调色习惯的 HSL,再到近几年才被浏览器广泛支持的感知均匀色彩空间 OKLCH——选对表示法,能让颜色的维护与调整轻松许多。

传统表示法

写法示例说明
关键字rebeccapurple148 个预定义颜色名,可读但精度有限
十六进制#8a5a2e最常见,也支持 4/8 位写法附带透明度
rgb()rgb(138 90 46)红绿蓝三通道,0–255 或百分比
.accent {
  color: #8a5a2e;
  color: rgb(138 90 46); /* 等价写法,空格分隔是现代语法 */
}

hsl:符合直觉的调色方式

hsl(色相 饱和度 明度) 用三个更贴近人类直觉的维度描述颜色,调整"更深一点"或"更鲜艳一点"时,不需要像 RGB 那样同时心算三个通道。

:root {
  --accent: hsl(30 47% 36%);
  --accent-light: hsl(30 47% 56%); /* 只改明度,颜色关系保持一致 */
}
同色相不同明度
30%
45%
60%
75%

透明度的两种写法

现代语法允许在颜色函数内用斜杠追加透明度,不再需要专门记忆 rgba() / hsla() 这类"a 后缀"函数(它们仍可用,但已是历史写法):

.overlay {
  background: hsl(240 20% 10% / .6);
  border: 1px solid rgb(255 255 255 / .12);
}
易混淆点opacity 作用于整个元素(含内容与子元素),会让文字也一起变淡;而颜色值里的 alpha 通道只影响这一处颜色本身,两者场景不同,不要混用。

oklch:感知均匀的现代色彩空间

HSL 有一个隐藏问题:同样的明度数值,在不同色相下人眼感知到的亮度并不一致(比如同明度的黄色看起来比蓝色亮得多)。OKLCH 用感知均匀的方式定义颜色,相同的明度差在任意色相下观感一致,非常适合生成色阶。

.accent {
  color: oklch(52% 0.09 48); /* 明度 色度 色相角 */
}

目前主流现代浏览器已支持 oklch,用于生成设计系统色阶时优先考虑;面向仍需兼容旧浏览器的项目,可保留 hsl 作为回退值——CSS 会自动忽略无法解析的属性值,保留最后一条生效的声明。

currentColor 与 transparent

currentColor 是一个特殊关键字,代表元素当前生效的 color 值,让边框、阴影等属性可以"继承"文字颜色,减少重复声明:

.icon-btn {
  color: #3f5d54;
  border: 1px solid currentColor; /* 边框自动跟随文字色 */
}

color-mix()

无需手动计算,直接在 CSS 里按比例混合两种颜色——生成悬停态、禁用态等派生色时非常实用:

.btn:hover {
  background: color-mix(in srgb, #8a5a2e 85%, black);
}

Chapter 7 · Section 7.1

Color Systems and Transparency


CSS offers more than one way to describe color: from the most basic hexadecimal values, to HSL which matches how designers mix colors, to OKLCH — a perceptually uniform color space that browsers only widely supported in recent years. Choosing the right notation makes maintaining and adjusting colors much easier.

Traditional Notations

NotationExampleDescription
Keywordrebeccapurple148 predefined color names; readable but limited precision
Hexadecimal#8a5a2eThe most common; the 4/8-digit forms also include alpha
rgb()rgb(138 90 46)Red, green, blue channels; 0–255 or percentages
.accent {
  color: #8a5a2e;
  color: rgb(138 90 46); /* equivalent syntax; space-separated is the modern form */
}

hsl: An Intuitive Way to Mix Colors

hsl(hue saturation lightness) describes color with three dimensions closer to human intuition. When you want something "a bit darker" or "more vivid", you do not need to mentally recompute all three RGB channels at once.

:root {
  --accent: hsl(30 47% 36%);
  --accent-light: hsl(30 47% 56%); /* only lightness changes; the color relationship stays consistent */
}
Same hue, different lightness
30%
45%
60%
75%

Two Ways to Write Transparency

Modern syntax lets you append alpha with a slash inside the color function, so you no longer need to memorize "a-suffix" functions like rgba() / hsla() (they still work, but are now legacy):

.overlay {
  background: hsl(240 20% 10% / .6);
  border: 1px solid rgb(255 255 255 / .12);
}
Easy to confuseopacity affects the entire element (including its content and children), so text fades along with it; the alpha channel in a color value affects only that one color. They serve different purposes, so do not mix them up.

oklch: A Perceptually Uniform Modern Color Space

HSL has a hidden problem: the same lightness value is not perceived as equally bright across different hues (for example, a yellow at the same lightness looks much brighter than a blue). OKLCH defines colors in a perceptually uniform way — the same lightness difference looks consistent under any hue, which makes it ideal for generating color scales.

.accent {
  color: oklch(52% 0.09 48); /* lightness chroma hue angle */
}

Mainstream modern browsers already support oklch; prefer it when generating design-system color scales. For projects that still need to support older browsers, keep hsl as a fallback — CSS automatically ignores property values it cannot parse and keeps the last valid declaration.

currentColor and transparent

currentColor is a special keyword representing the element's currently effective color value, letting properties like border and shadow "inherit" the text color and reducing repeated declarations:

.icon-btn {
  color: #3f5d54;
  border: 1px solid currentColor; /* the border automatically follows the text color */
}

color-mix()

No manual calculation needed — mix two colors proportionally right in CSS. Very useful for generating derived colors like hover and disabled states:

.btn:hover {
  background: color-mix(in srgb, #8a5a2e 85%, black);
}