设计系统中推荐用 oklch(),因其 l 值基于 cie 2002 感知模型校正,同一 l(如 60%)在所有色相下视觉明度一致,而 hsl() 的 l 仅为 rgb 极值算术平均,同为 50% 时红绿亮度实测差三倍;l 必须带 % 单位,降级色须置于 @supports 外部上方,否则整行静默失效。

设计系统中推荐用 oklch(),是因为它能让同一明度值(L)在所有色相下真正“看起来一样亮”,而 hsl() 或 #hex 做不到——这不是体验优化,是基础工程需求。
oklch() 的 L 值能锚定感知亮度,hsl() 的 L 只是数学平均
hsl(0, 100%, 50%)(纯红)和 hsl(120, 100%, 50%)(纯绿)的 L 都是 50%,但实测 CIE Y 亮度分别是 ~0.21 和 ~0.72,视觉上差三倍。oklch() 的 L 是基于 CIE 2002 感知模型校正过的坐标,oklch(60% 0.28 0) 和 oklch(60% 0.28 120) 才真正在人眼看来明暗一致。
- 深色模式切换时,只需统一改
L:比如从oklch(62% 0.28 258.5)→oklch(38% 0.28 258.5),文字可读性平滑过渡 - 禁用态不能降
L,只降C:比如oklch(0.62 0.28 258.5)→oklch(0.62 0.12 258.5),避免浅底文字对比度断崖下跌 -
L必须带单位:oklch(60% 0.28 258.5)✅,oklch(60 0.28 258.5)❌(所有浏览器静默忽略整行)
@supports 降级结构稍错,UI 就直接变黑或透明
oklch() 不支持时不会报错,而是整条声明被跳过。如果 fallback 写错位置或检测值缺单位,用户看到的就是未定义背景色(常为透明或继承色)。
- 降级色必须写在
@supports块**外部且上方**:background-color: #2563eb;再跟@supports (color: oklch(0% 0 0)) { ... } - 检测值必须带
%:@supports (color: oklch(0% 0 0))✅,@supports (color: oklch(0 0 0))❌(Safari/Chrome/Firefox 全部返回 false) - 绝对不要用
@supports not—— 安卓 WebView 有解析 bug,会直接丢弃整块规则 - 别用
oklab()检测 —— 目前所有主流浏览器都返回 false
渐变和动画里色相跨 0° 边界必须手动拆段
CSS 对 oklch() 渐变不做色相短弧插值。写 oklch(0.7 0.25 350) → oklch(0.7 0.25 10),浏览器会按数值走 350→360→10,中间段 C 被强制压缩,出现灰紫色带。
- 色相差超过 180° 时,必须拆成两段:
linear-gradient(oklch(0.7 0.25 350), oklch(0.7 0.25 0), oklch(0.7 0.25 10)) - 混用色彩空间(比如其中一段写
hsl())会让整条渐变 fallback 到 sRGB 插值,前功尽弃 - 想保明保鲜,就固定
L和C,只调H;做深色模式悬停,就固定C和H,只调L
最常被忽略的不是“怎么写”,而是单位细节和 fallback 顺序——错一个 %,整行失效;降级色写错位置,老设备上 UI 就不可用。OKLCH 的优势只在全链路统一、严格守规时才成立。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











