OKLCH不是HSL升级版,而是基于人眼感知模型的替代方案:调L不偏色、调C不变亮、调H不失饱和;其L为CIE 2002校正的感知亮度坐标,与HSL数学平均L语义不同,不可直接套用,须重采样转换且L必须带单位。

OKLCH 不是 HSL 的“升级版”,它是用另一套人眼感知模型替代了 HSL 的数学平均逻辑——调 L 真的不偏色,调 C 真的不改亮,调 H 真的不失饱和。但前提是写对、用对、降级对。
oklch() 的 L 值为什么不能直接套用 hsl() 的数值
HSL 的 L 是 RGB 三通道最大值与最小值的算术平均,纯数学构造;OKLCH 的 L 是 OKLab 空间中经 CIE 2002 校正的感知亮度坐标。实测显示:hsl(0, 100%, 50%)(纯红)CIE Y 亮度约 0.21,hsl(120, 100%, 50%)(纯绿)约 0.72,差三倍;而 oklch(0.5 0.32 0) 和 oklch(0.5 0.32 120) 才真正视觉等亮。
常见错误是把品牌色 hsl(240, 70%, 50%) 直接改成 oklch(50% 0.28 240),结果蓝变灰紫。正确做法是用在线转换器重采样,例如 hsl(240, 100%, 50%) ≈ oklch(0.54 0.32 240)。
@supports 检测和 fallback 写法最容易失效的三个点
OKLCH 不支持时不是报错,而是整条声明被静默忽略——如果 fallback 写得不对,UI 就直接变黑、变透明或错色。
立即学习“前端免费学习笔记(深入)”;
- 降级色必须写在
@supports块外部且上方:background-color: #2563eb;,再包裹@supports (color: oklch(0% 0 0)) { ... } - 检测值必须带单位:
@supports (color: oklch(0% 0 0))✅,@supports (color: oklch(0 0 0))❌(Safari 17.4+ 也返回 false) - 别用
@supports not,安卓 WebView 存在解析 bug;也别用oklab()检测,目前所有主流浏览器都返回 false
linear-gradient 中跨 0°/360° 色相会出灰紫色带
CSS 对 oklch() 渐变不做色相短弧优化。oklch(0.7 0.25 350) → oklch(0.7 0.25 10) 会从 350° 经过 0°、10° 插值,数值上是 350→360→10,导致中间段色度被强制拉低,出现难看的灰紫色带。
解决方法只有手动拆段:
- 色相差超过 180° 时,必须写成:
linear-gradient(oklch(0.7 0.25 350), oklch(0.7 0.25 0), oklch(0.7 0.25 10)) - 所有节点必须统一用
oklch(),混用rgb()或hsl()会导致插值 fallback 到 sRGB 空间,失去感知均匀性
禁用态和深色模式必须用不同策略调参
OKLCH 的一致性来自参数分工明确,但调参逻辑不能一概而论:
- 禁用态:固定
H和L,只降C—— 例如从oklch(0.62 0.28 258.5)→oklch(0.62 0.12 258.5),避免文字在浅底上可读性断崖下跌 - 深色模式:固定
H和C,只调L—— 例如oklch(0.62 0.28 258.5)→oklch(0.38 0.28 258.5),视觉过渡平滑,不发青也不发紫
最容易被忽略的是:L 必须带单位(50% 或 0.5),缺单位则整条声明静默失效;Chrome DevTools 在 computed 样式里永远只显示降级后的 sRGB 十六进制值,看不到真实 OKLCH 行为。


















