什么是 HSB/HSV?和 HSL 是一回事吗

两套模型的定义差别、与 RGB 的换算关系、PS/Figma 滑块怎么看,以及用 HSB 微调颜色的手法

设计师在 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 也几乎都不相等。看一组对照最直观:

颜色HEXHSB(HSV)HSL
纯红#FF00000, 100%, 100%0, 100%, 50%
浅红#FF66660, 60%, 100%0, 100%, 70%
品牌蓝#1677FF215, 91%, 100%215, 100%, 54%
中灰#8080800, 0%, 50%0, 0%, 50%
最容易记错的一条:HSB 里 B=100% 是纯色,HSL 里 L=50% 才是纯色。把 HSB 的 B 当成 HSL 的 L 填进去,颜色会一路冲到白。

二、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)];
}
手算时最省事的判断:max 和 min 相等(也就是灰色)时,S 一律是 0,色相无意义。除此之外,HSL 的 S 通常比 HSB 的 S 大,因为它的分母更小。

三、PS/Figma 拾色器里的滑块怎么看

Photoshop 的拾色器给了一组单选,可以在 HSB 与 HSL 之间切换——选 B 时第三根滑块是明度,选 L 时变成亮度。Figma 的颜色面板则是固定的 H、S、B,没有 HSL 这个选项。

麻烦出在下游。CSS 只认 hsl() 和 hsla(),从来没有 hsb()。设计稿里那三个数是按 HSB 读的,直接粘进样式表,等于把明度当亮度用。

  1. 先确认工具读的是哪一套:Figma 面板、Photoshop 默认都是 HSB,别想当然当成 HSL。
  2. 落进 CSS 前先转一次:把 HSB 转成 HSL 或直接取 HEX,两个都不容易出错。
  3. 交付环节省一步:让设计稿直接标注 HEX,前端不用在心里做模型换算。
不想自己按公式算,可以把数值丢进 颜色转换工具,HEX、RGB、HSL 会一起列出来,复制哪一份都能用。

四、用 HSB 快速微调颜色

HSB 在"手动调色"这件事上比 HSL 顺手,原因是三个滑块的方向很直白:S 往左是掺白,B 往左是掺黑。想让一个颜色变浅还是变暗,动哪根滑块不用想。

  • 换同色系:只拖 H,S 和 B 保持不动,得到的是同一"浓度"下的邻近色。
  • 调浅(加白):B 不动,把 S 往下拉,颜色沿直线走向白。
  • 调深(加黑):S 不动,把 B 往下拉,颜色沿直线走向黑。
  • 做按钮状态色:H 和 S 锁死,只改 B——悬停态压一点,按下态再压一点,色相不会跑偏。

HSL 做同一件事时会别扭一点:想加白得把 L 往上推,加到 100% 就彻底变白,中间那段"稍微亮一点"的范围比 HSB 的 S 要窄,手感差一些。

想直接拖着试,用 色相环工具,它走的就是 HSV 模式,滑块布局和 Photoshop、Figma 里看到的一致,拖出来的手感不用重新适应。

HSB 和 HSL 共用同一个色相,饱和度和第三个分量的算法却完全不同:一个的分母是最亮通道,一个随亮度浮动。设计工具读的是 HSB,CSS 写的是 HSL,两边数字对不上是常态,复制之前先转一次就不会翻车。调色时 HSB 更直觉——往左掺白、往下掺黑,两根滑块各管一头。