你在同事的代码里看到 background: #FFF,自己写的是 #FFFFFF。两个都跑得通,你以为是两种颜色。其实浏览器把 #FFF 读成 #FFFFFF,渲染出来一模一样。剩下要弄清楚的是:哪些颜色能写成三位。
一、3 位 HEX 的成立条件
六位 HEX 是两两一组:RR、GG、BB,分别对应红、绿、蓝三个通道。能缩成三位的条件很硬:每一组的两个字符必须相同。
#FFFFFF 拆成 FF、FF、FF,三组各自两位都相同,所以能写成 #FFF。#FF6600 拆成 FF、66、00,同样满足,能写成 #F60。而 #FF6B35 里的 6B 和 35 两位不同,它就只能保持六位。
| 六位写法 | 三个分组 | 能否简写 |
|---|---|---|
#FFFFFF | FF / FF / FF | 能 → #FFF |
#FF6600 | FF / 66 / 00 | 能 → #F60 |
#336699 | 33 / 66 / 99 | 能 → #369 |
#FF6B35 | FF / 6B / 35 | 不能 |
#1A1A2E | 1A / 1A / 2E | 不能 |
一句话记住:六位里每组两位相同,这一组才能压成一位。这是唯一的判断标准,跟颜色本身是什么色相、常不常用都没有关系。
二、#FFF 展开成 #FFFFFF 的规则
展开规则是每一位复制一次。#F60 的第一位 F 变成 FF,第二位 6 变成 66,第三位 0 变成 00,合起来就是 #FF6600。
#FFF → #FFFFFF
#F60 → #FF6600
#369 → #336699
#ABC → #AABBCC
浏览器只在解析的那一刻做这个展开。你在源码里写三位还是六位,最终送进渲染的都是同一个像素值,不存在精度差别。
注意是复制,不是取整:展开过程不涉及任何四舍五入,所以简写不会丢失颜色信息。#F60 和 #FF6600 是同一个值,不是近似值。
三、4 位与 8 位 HEX(带 Alpha)
六位后面再加两位就是 8 位,最后两位表示透明度;三位后面加一位就是 4 位,那一位同样表示透明度。展开规则一致——每位复制一次。
| 位数 | 结构 | 示例 | 展开结果 |
|---|---|---|---|
| 3 位 | RGB | #F60 | #FF6600 |
| 4 位 | RGBA | #F608 | #FF660088 |
| 6 位 | RRGGBB | #FF6600 | 已是最长 |
| 8 位 | RRGGBBAA | #FF660088 | 已是最长 |
/* 4 位:橙色 + 约 53% 不透明 */
background: #F608; /* 展开为 #FF660088 */
/* 等价的 rgba 写法 */
background: rgba(255, 102, 0, 0.53);
最容易算错的一步:Alpha 用的是十六进制。
00 全透明,FF 完全不透明,而 88 是 136/255,约等于 53%,不是 88%。四、简写与全写的兼容性
三位的支持范围最广,从 CSS1 就有,老版本 IE 也能解析。四位和八位出现得晚,属于 CSS Color 4,现代浏览器都支持,但 IE 不认。
- 面向现代浏览器:三位、四位、六位、八位都能用,选最顺手的那个。
- 需要兼容旧环境:用六位加 rgba() 表达透明度,避开四位和八位。
- 设计工具导出的值:Figma、Sketch 给的是六位,直接复制进代码即可。
团队约定建议:提交的代码统一用六位(带透明度时用八位或 rgba),三位只在你临时手打时用。混排的话,读代码的人得在脑子里额外展开一遍。
五、如何快速判断能否简写
把六位拆成三组,逐组看两位是否相同。练几次之后扫一眼就能出结果:
- 看第 1、2 位是否相同(RR 组)。
- 看第 3、4 位是否相同(GG 组)。
- 看第 5、6 位是否相同(BB 组)。
- 三组都相同才能写成三位;有一组不同就不行。
试两个:#00CC99 拆成 00、CC、99,三组都相同,能写成 #0C9;#FF6B35 的第二组 6B 两位不同,只能保持六位。
六位 HEX 里每组两位相同,这一组就能压成一位——简写的规则只有这一条。以后看到 #FFF 和 #FFFFFF 并存,不用纠结哪个更正确,它们送进渲染的是同一个像素值,区别只在写法。