/* 十六进制 */ #0969da /* 6 位:RRGGBB */ #0969da80 /* 8 位:RRGGBBAA,最后两位是透明度(00 全透明,FF 不透明) */ #069 /* 3 位缩写 = #006699,只有每对数字相同才能缩写 */ /* 函数式:现代写法用空格分隔,不需要逗号 */ rgb(9 105 218) rgb(9, 105, 218) /* 新/旧语法都支持 */ rgb(9 105 218 / 0.5) rgb(9 105 218 / 50%) hsl(212 92% 45%) /* 色相 0–360,饱和度、亮度百分比 */ hsl(212 92% 45% / 50%) hwb(212 4% 15%) /* 白量、黑量,比 hsl 更符合「调深浅」的直觉 */ oklch(52% 0.19 253) /* 感知均匀:亮度百分比越接近视觉明度,彩度 0–0.4 左右 */ lab(...) lch(...) color(display-p3 …) color(srgb …) /* 其它色彩空间 */ transparent currentColor inherit /* 三个特殊关键字 */
上面第二个格子故意写成 #069da:5 位十六进制非法,浏览器整条声明丢弃,所以那块是默认底色——这就是「颜色不生效」最常见的一个原因,缩写只能 3 位或 6 位。
| 写法 | 适合 | 原因 |
|---|---|---|
#RRGGBB | 固定的品牌色、设计稿直接取色 | 最短、工具里最好读 |
#RRGGBBAA | 需要一次性写透明色 | 一个 token 搞定,不用函数 |
hsl() / hwb() | 需要成组地调明暗、生成变体 | 改一个数字就能出一系列色阶,比改 hex 直观得多 |
rgb(… / a) | 由 JS 计算出的颜色、需要单独控制透明度 | 与取值 API 天然一致 |
oklch() | 做色阶系统、深浅主题 | HSL 的「50% 亮度」在不同色相下视觉明度差很多(黄色亮、蓝紫暗);OKLCH 是感知均匀的,同一 L 值的各色看起来真的同样亮 |
| 颜色关键字 | 临时试色 | 147 个 CSS 命名色(royalblue 等)加 transparent/currentColor;正式项目不建议,读代码时要查表 |
/* 颜色的 alpha:只有这一层颜色透明,文字仍然清晰 */ background: rgb(9 105 218 / 0.5); /* 元素的 opacity:整层(含文字、子元素、边框)一起透明,并会创建层叠上下文 */ opacity: .5;
currentColor 是个实用工具:它取当前元素的 color 值,所以 border-color: currentColor、box-shadow: 0 0 0 3px currentColor 会随主题自动跟随,不需要额外维护变量。
/* 不要把颜色硬写进组件,交给变量(第十四章展开) */
:root { --c-primary: #0969da; --c-bg: #fff; --c-text: #24292f; }
html[data-theme='dark'] { --c-primary: #6aa8ff; --c-bg: #0d1117; --c-text: #e6edf3; }
.card { background: var(--c-bg); color: var(--c-text); border-color: var(--c-primary); }
暗色主题下不要简单地把颜色取反:深蓝底配高饱和品牌色容易「发光」刺眼,通常要把饱和度降下来、明度提上去(这正是 oklch() 好用的地方——只调 L 与 C,保持色相不变)。另外 color-scheme: light dark 这一行能让浏览器的默认控件、滚动条、表单底色一起切换,成本极低但收益明显。