设计师在 Figma 里调好的蓝色,面板上写着 215、91、100。你把这三个数原样填进 CSS 的 hsl(215, 91%, 100%),页面上一片白。数字一个没改,颜色却差得离谱——问题不在你手抖,而在 B 和 L 根本不是同一个东西。
一、HSB 与 HSL 的定义差异
两套模型的第一位是相同的:H(Hue,色相)都是色相环上的角度,0° 红、120° 绿、240° 蓝,范围 0–360。真正容易混的是后两位——它们名字像,算法完全不同。
HSB(也叫 HSV)的三个分量
- S 饱和度:当前颜色离"纯色"还差多少白。S=100% 表示没掺白,S=0 就是白或灰。
- B 明度(V):取 RGB 三个通道里最亮的那个值。B=100% 是纯色最亮的状态,B=0 一定是黑。
HSL 的三个分量
- S 饱和度:离"同一亮度下的灰"还差多远。它衡量的是鲜艳程度,不是掺了多少白。
- L 亮度:取最亮通道与最暗通道的平均值。L=50% 才是纯色,L=100% 是白,L=0 是黑。
同一个颜色在两套模型里的 S 几乎都不相等,L 和 B 也几乎都不相等。看一组对照最直观:
| 颜色 | HEX | HSB(HSV) | HSL |
|---|---|---|---|
| 纯红 | #FF0000 | 0, 100%, 100% | 0, 100%, 50% |
| 浅红 | #FF6666 | 0, 60%, 100% | 0, 100%, 70% |
| 品牌蓝 | #1677FF | 215, 91%, 100% | 215, 100%, 54% |
| 中灰 | #808080 | 0, 0%, 50% | 0, 0%, 50% |
二、HSB、HSL、RGB 的换算关系
两套模型都从 RGB 的 max 和 min 算起,色相 H 的推导过程完全一样,差别只在 S 的分母和第三个分量。记住这四条就够了(以下 RGB 按 0–1 归一化):
V = max /* HSB 的明度 */
L = (max + min) / 2 /* HSL 的亮度 */
S_hsb = (max - min) / max /* 分母是最亮通道 */
S_hsl = (max - min) / (1 - |2L - 1|) /* 分母随亮度变化 */
写成代码就是下面这样。色相部分两套共用,只算一次:
function rgbToHsb(r, g, b) {
const max = Math.max(r, g, b), min = Math.min(r, g, b);
const d = max - min;
let h = 0;
if (d !== 0) {
if (max === r) h = 60 * (((g - b) / d) % 6);
else if (max === g) h = 60 * ((b - r) / d + 2);
else h = 60 * ((r - g) / d + 4);
}
if (h < 0) h += 360;
const s = max === 0 ? 0 : (d / max) * 100;
return [Math.round(h), Math.round(s), Math.round((max / 255) * 100)];
}
function rgbToHsl(r, g, b) {
const max = Math.max(r, g, b), min = Math.min(r, g, b);
const d = max - min;
const l = (max + min) / 2 / 255;
let h = 0;
if (d !== 0) { /* 色相算法与上面完全一致 */ }
const s = d === 0 ? 0 : ((d / 255) / (1 - Math.abs(2 * l - 1))) * 100;
return [Math.round(h), Math.round(s), Math.round(l * 100)];
}
三、PS/Figma 拾色器里的滑块怎么看
Photoshop 的拾色器给了一组单选,可以在 HSB 与 HSL 之间切换——选 B 时第三根滑块是明度,选 L 时变成亮度。Figma 的颜色面板则是固定的 H、S、B,没有 HSL 这个选项。
麻烦出在下游。CSS 只认 hsl() 和 hsla(),从来没有 hsb()。设计稿里那三个数是按 HSB 读的,直接粘进样式表,等于把明度当亮度用。
- 先确认工具读的是哪一套:Figma 面板、Photoshop 默认都是 HSB,别想当然当成 HSL。
- 落进 CSS 前先转一次:把 HSB 转成 HSL 或直接取 HEX,两个都不容易出错。
- 交付环节省一步:让设计稿直接标注 HEX,前端不用在心里做模型换算。
四、用 HSB 快速微调颜色
HSB 在"手动调色"这件事上比 HSL 顺手,原因是三个滑块的方向很直白:S 往左是掺白,B 往左是掺黑。想让一个颜色变浅还是变暗,动哪根滑块不用想。
- 换同色系:只拖 H,S 和 B 保持不动,得到的是同一"浓度"下的邻近色。
- 调浅(加白):B 不动,把 S 往下拉,颜色沿直线走向白。
- 调深(加黑):S 不动,把 B 往下拉,颜色沿直线走向黑。
- 做按钮状态色:H 和 S 锁死,只改 B——悬停态压一点,按下态再压一点,色相不会跑偏。
HSL 做同一件事时会别扭一点:想加白得把 L 往上推,加到 100% 就彻底变白,中间那段"稍微亮一点"的范围比 HSB 的 S 要窄,手感差一些。
HSB 和 HSL 共用同一个色相,饱和度和第三个分量的算法却完全不同:一个的分母是最亮通道,一个随亮度浮动。设计工具读的是 HSB,CSS 写的是 HSL,两边数字对不上是常态,复制之前先转一次就不会翻车。调色时 HSB 更直觉——往左掺白、往下掺黑,两根滑块各管一头。