自给自足。代码:https://laputaz.github.io/color-converter/
在线 Demo: https://laputaz.github.io/color-converter/
背景
在日常的 css 编写中,经常会和色值打交道,最常见的几种格式便是:
1 | color: #12fe21; |
这三种色值分别称为:hex 色值,rgb 色值,hsl 色值。
色值组成
那么这三种色值为什么是这么表示的呢?首先有一个“原色”的概念:
原色是指不能透过其他颜色的混合调配而得出的“基本色”。 –wiki
常见的说法是,三原色为:红、绿、蓝。但是这个说法不是固定的,“原色”并不是一个物理概念,而是一个生物概念,是指人的肉眼对于光线的生理作用。在显示,印刷,和绘画等领域,“三原色”定义都可能不一样。
而以上提到的三种色值表示法,使用的是三原色光模式 RGB (红、绿、蓝)。
hex
hex 也就是 hexadecimal,十六进制表示法。因为是 16 进制,所以每一位的取值范围都是 0 ~ f
, 其中:
前 2 位代表红色的浓度,中间 2 位代表绿色浓度,最后 2 位代表蓝色浓度。
#ff0000 => 纯红色
#00ff00 => 纯绿色
#0000ff => 纯蓝色
当每两位数值一样的时候,可以简写,如:
#f00 => 纯红色
一些浏览器支持 8 位,末尾两位为透明度:
#ff000088 => 纯红色半透明
按照这种关系,那就可以随意组合了,例如:
#ffff00 => 红色+绿色=黄色
#ff00ff => 红色+蓝色=品红
#00ffff88 => 绿色+蓝色+半透明=半透明靛青
rgb
rgb 表示法,跟 hex 类似,只是采用了 10 进制表示数字,前面提到的 hex 表示法,用两位 16 进制数表示一个颜色,所以转换成十进制的话,一共有 16*16=256 种组合,即范围是 0 ~ 255
:
rgb(255,0,0) => 纯红色
rgb(0,255,0) => 纯绿色
rgb(0,0,255) => 纯蓝色
同样,可以增加一位,表示透明度,这个时候就要写成 rgba
了,其中 a 表示 阿尔法通道(α Channel或Alpha Channel)是指一张图片的透明和半透明度。
,取值是 0 ~ 1
。
rgba(0, 255, 255, 0.5) => 绿色+蓝色+半透明=半透明靛青
hsl
hsl 和 前面两种表示方式有一些区别,hsl 指的是 色相、饱和度、亮度(Hue, Saturation, Lightness)
色相(H)是色彩的基本属性,就是平常所说的颜色名称,如红色、黄色等。
饱和度(S)是指色彩的纯度,越高色彩越纯,低则逐渐变灰,取 0-100%的数值。
明度(V),亮度(L),取 0-100%。
表示方式:
hsl(0deg 100% 50%) => 纯红色
hsl(120deg 100% 50%) => 纯绿色
hsl(240deg 100% 50%) => 纯蓝色
同样,可以增加一位表示透明度, 改写成 hsla:
hsla(240deg, 100%, 50%, 50%) => 半透明纯蓝色
色值转换
这里主要说 hex 和 rgb 的转换,至于 hsl 比较复杂,它是将 rgb 使用的笛卡尔坐标系转换成用圆柱坐标系来表示,所以涉及到几何、向量等计算,早就忘光了。有兴趣可以看:

hex 转换成 rgb
也就是每两位 16 进制转换成 10 进制,比较简单,如 ef 转换成 10 进制是 15 * 16**0 + 14 * 16**1
。
代码实现:
1 | // 错误信息 |
rgb 转换成 hex
将 10 进制数转换成 2 位的 16 进制数,思路是:
- 转换后的事必须是 2 位,所以第 2 位必须是能被 16 整除的,否则不可能进位
- 第一位最大是 15 (f)
数字减去 15 后,仍能被 16 整除,以这个思路不断循环即可,例如 (254 - 15) / 16 = 15,那么结果就是 15 15 => ff
或者更简单的是,直接用 toString():
1 | const num = 255 |
代码实现:
1 | const WRONG_MESSAGE = '' |
Demo
这里部署了一个在线的 Demo:
https://laputaz.github.io/color-converter/
