OKLCH是唯一实现L、C、H三通道解耦的颜色函数:调L不偏色、调C不变亮、调H不失饱和;其L为经CIE 2002校正的感知亮度坐标,与HSL的数学平均L本质不同,数值不可直接套用。

oklch() 不是“更适合”,它是目前唯一能让 L(亮度)、C(色度)、H(色相)三者真正解耦、各自独立影响视觉感知的颜色函数——调 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 检测写错就全失效
oklch() 不支持时不是报错,而是整条声明被静默忽略。如果 fallback 写得不对,UI 就直接变黑、透明或错色。
- 降级色必须写在
@supports块外部且上方,比如先写background-color: #2563eb; - 检测值必须带单位:
@supports (color: oklch(0% 0 0))✅,@supports (color: oklch(0 0 0))❌ - 绝对不用
@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 → 360 → 10,中间段 H=0° 附近 C 被强制压缩,出现难看的灰紫色带。
立即学习“前端免费学习笔记(深入)”;
- 色相差 >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)
最常被忽略的是:DevTools 在 computed 样式里永远只显示降级后的 sRGB 十六进制值,看不到真实 oklch() 行为;getComputedStyle(el).backgroundColor 返回的也永远是 sRGB 值。真值只能靠肉眼比对 + 限制 C ≤ 0.28 控制色域漂移风险。


















