HSL()中第二个参数控制纯度:0%为灰阶,100%为该色相最鲜艳基准色,中间值线性缩放色彩矢量径向长度;降饱和即向灰轴靠拢,如hsl(120,0%,50%)恒为#808080。

hsl()里第二个参数到底控制什么
它控制的是纯度,不是“颜色浓淡”这种模糊概念——0% 是完全去色的灰阶,100% 是该色相下最鲜艳的基准色。中间值线性缩放色彩矢量在圆柱坐标系中的径向长度,所以降饱和度本质是往中心轴(灰轴)靠拢。
-
hsl(120, 0%, 50%)是纯灰(#808080),和hsl(0, 0%, 50%)、hsl(240, 0%, 50%)渲染结果完全一样 - 别用整数百分比硬凑,比如想“稍微降一点”,
hsl(120, 85%, 50%)比hsl(120, 90%, 50%)更柔和,人眼对高饱和区敏感度下降 - CSS 里不支持变量插值运算,
hsl(var(--h), calc(var(--s) * 0.7), var(--l))会报错,得用 CSS 自定义属性 + JS 或预处理器处理
直接写 hsl() 时怎么选数值才不翻车
浏览器解析 hsl() 时对空格和逗号宽松,但数值越界行为不一致:Chrome 把 hsl(120, 150%, 50%) 当作 hsl(120, 100%, 50%),Firefox 却可能拒绝渲染或回退到继承色。
- 饱和度必须写成
0%~100%闭区间,写100(缺%)或-10%都无效 - 明度同理:
hsl(120, 60%, 0)是黑,hsl(120, 60%, 100)是白,缺%会被忽略,变成hsl(120, 60%, 0%)或hsl(120, 60%, 100%),取决于浏览器 - 色相可省略单位,
hsl(120, 60%, 50%)和hsl(120deg, 60%, 50%)等价,但别混用120rad这种非法单位
用 JS 动态改饱和度要注意什么
从 getComputedStyle(el).color 读出来的几乎永远是 rgb() 或十六进制,没有现成的 hsl() 值——得先转再改,否则直接拼字符串容易出错。
- 别用正则粗暴替换:
rgb(100, 200, 50)→hsl(120, 60%, 50%)→ 改饱和度 → 再转回 rgb,链式转换有精度损失 - 推荐用
chroma.js或手写 RGB→HSL 转换函数,重点校验 HSL 中的 S 分量是否在 [0, 1] 浮点区间,再乘以 0.8 这类系数 - 如果只是 hover 变暗,用
filter: saturate(0.7)更轻量,但它作用于整个元素(含子元素和图片),而hsl()只改当前色值
对比 filter: saturate() 和 hsl() 调整的区别
前者是后处理效果,后者是颜色定义本身——这导致它们在层级、继承和性能上完全不同。
立即学习“前端免费学习笔记(深入)”;
-
filter: saturate(0.5)会让文字阴影、边框、背景图一起变灰;color: hsl(120, 30%, 50%)只影响文字本身颜色 - filter 在合成层触发重绘,大量使用可能卡顿;hsl() 是样式计算阶段完成,无额外开销
- filter 不影响伪元素的
content颜色继承,但 hsl() 定义的color会正常继承给::before
实际项目里,如果你只调一个文字颜色,hsl() 直接改第二个参数最干净;但要是按钮带图标+文字+边框整体降饱和,filter 更省事。不过得记住:filter 的值是乘数(saturate(0) = 完全去色),而 hsl() 的第二个参数是绝对值(hsl(..., 0%, ...) = 完全去色),别把这两个 0% 当成一回事。










