设计稿给的是 #c0392b,代码里要写 rgb(),调色时又听说该用 hsl()——这三种写法到底什么关系,什么时候该用哪个?这篇文章讲清楚。
它们描述的是同一个东西:屏幕上一个颜色由红、绿、蓝三束光按不同强度混合而成。区别只在“怎么写”和“写起来方不方便调”。
| 写法 | 示例 | 含义 |
|---|---|---|
| HEX | #c0392b | 红 c0、绿 39、蓝 2b(十六进制) |
| RGB | rgb(192, 57, 43) | 红 192、绿 57、蓝 43(十进制) |
| HSL | hsl(6, 61%, 46%) | 色相 6°、饱和度 61%、亮度 46% |
前两个本质相同,只是进制不同:c0 十六进制 = 192 十进制。第三个数是换了一套坐标系统来描述同一个颜色。
RGB 的取值范围是 0-255,每个通道刚好占一个字节。HEX 就是把这三个数用十六进制写在一起:
RGB(192, 57, 43)
192 → c0
57 → 39
43 → 2b
拼起来 → #c0392b
常见的简写形式 #fff 等价于 #ffffff,只在每两位数字相同时可用(#ff → #ffff)。#abc 是 #aabbcc。
#000 比 rgb(0,0,0) 省事rgba(192, 57, 43, 0.5)#c0392b80 这种 8 位 HEX 也能表示透明度(末尾两位是 alpha),但 rgba() 可读性更好,团队协作时更不容易看错。HSL 把颜色拆成三个和人直觉更接近的维度:
| 分量 | 范围 | 含义 |
|---|---|---|
| H 色相 | 0-360 | 色环上的角度:0° 红、120° 绿、240° 蓝 |
| S 饱和度 | 0%-100% | 0% 是灰,100% 是最鲜艳 |
| L 亮度 | 0%-100% | 0% 黑,100% 白,50% 是正常 |
它的价值在于:想调出同一色系的不同深浅,只改 L 就行。
hsl(6, 61%, 30%) 深红
hsl(6, 61%, 46%) 原色 ← 同一色系
hsl(6, 61%, 70%) 浅红
换成 HEX 你得挨个算,而且不好保证“是同一色系”。所以设计系统里常把主色存成 HSL,再程序化生成 hover 态、禁用态、浅色背景。
颜色选得好不好看是审美问题,文字看不看得清是可用性问题。WCAG 给出了明确的数字要求:
| 级别 | 正文文字 | 大号文字 |
|---|---|---|
| AA(最低要求) | 4.5 : 1 | 3 : 1 |
| AAA(更严格) | 7 : 1 | 4.5 : 1 |
“大号文字”指 18pt 以上,或者 14pt 加粗。
几个常见的坑:
#c0392b),点「转换」转换在浏览器本地完成,不上传任何数据。
opacity 会让整个元素(包括里面的文字和子元素)一起变透明;rgba() 只让这个颜色属性本身透明,文字依然清晰。要半透明背景但文字不透明,必须用 rgba()。hsl(0,0%,50%)、hsl(180,0%,50%)、hsl(300,0%,50%) 是完全一样的颜色。#rgba),8 位是完整写法加透明度(#rrggbbaa)。都受现代浏览器支持,但如果要兼容很老的浏览器,还是用 rgba()。