OKLCH颜色空间中L值统一设为60%可确保红、绿、蓝等色相视觉亮度一致,因其L是感知亮度坐标,而HSL的L仅为RGB极值算术平均,与人眼无关。

直接用 oklch() 定义颜色,L 值统一设为相同百分比(如 60%),且全程不混用 hsl() 或 rgb() —— 这样红、绿、蓝等不同色相在人眼看来才真正“一样亮”。这不是靠技巧“校准”,而是 OKLCH 空间本身的感知建模决定的。
为什么 hsl(0, 100%, 50%) 和 hsl(120, 100%, 50%) 实际亮度差一倍以上
HSL 的 L 是 RGB 三通道极值的算术平均,纯数学构造,和人眼无关。实测:hsl(0, 100%, 50%)(纯红)CIE Y 亮度约 0.21,hsl(120, 100%, 50%)(纯绿)约 0.72。OKLCH 的 L 是 OKLab 中的感知亮度坐标,同一 L=60% 下,所有色相都落在人眼敏感度中段。
常见错误现象:
- 用
hsl()写多色组件(如标签页、状态徽章),视觉层级混乱,绿色看起来“抢眼”,蓝色显得“发灰” - 深色模式下把所有
hsl(..., 30%)统一调暗,结果红色按钮变糊,青色图标却依然刺眼
oklch() 的 L 值必须带 % 单位,否则整条声明静默失效
oklch() 解析极其严格:缺单位、单位错、小数位过多,浏览器不是报错,而是直接跳过整行 CSS。这导致 UI 在某些设备上“突然变黑”或“全显 fallback 色”。
立即学习“前端免费学习笔记(深入)”;
安全写法只有两种:
-
oklch(60% 0.28 0)—— 兼容性最高,Chrome 112+ / Safari 16.4+ / Firefox 113+ 全支持 -
oklch(0.6 0.28 0)—— 仅 Chrome 112+/Firefox 121+/Safari 17.4+ 支持,且H值小数位建议 ≤1(258.5可,258.543在部分 Safari 版本里解析失败) -
oklch(60 0.28 0)❌ —— 缺%,被所有主流浏览器忽略 -
oklch(60% 28% 0)❌ ——C必须是无单位小数,不能写成百分比
多色组件中统一 L 值时,C 值要按色相微调
OKLCH 色域不是均匀的:同个 C=0.28,在蓝色区表现饱满,在黄色区可能已接近上限,再高就会被 clamp 或降级为灰阶。实际使用中,建议:
- 日常品牌色系统中,
C控制在 ≤0.28,兼顾表现力与跨设备一致性 - 若需更高饱和,优先试蓝(H≈240–270)和紫(H≈270–300),避免在黄(H≈40–60)和青(H≈160–190)上硬拉
C - 用
color-mix(in oklch, ...)做混合时,确保基色都在同一 OKLCH 范围内,否则混合结果不可控
@supports 检测必须写在 fallback 颜色之后,且检测值带单位
OKLCH 不支持时不是报错,而是整条声明被跳过。如果 fallback 写错位置或检测值单位不对,UI 就直接变透明、变黑或错色。
正确结构必须是:
button {
background-color: #2563eb;
}
@supports (color: oklch(0% 0 0)) {
button {
background-color: oklch(60% 0.28 258.5);
}
}
关键点:
- fallback 颜色(如
#2563eb)必须写在@supports块**外部且上方** - 检测值必须带单位:
oklch(0% 0 0)✅,oklch(0 0 0)❌(Safari 17.4+ 也返回 false) - 绝对不要用
@supports not—— 安卓 WebView 存在解析 bug - 别用
oklab()替代检测 —— 所有主流浏览器目前都返回 false
最容易被忽略的是:OKLCH 的 L 值不是“百分比亮度”,它是无量纲感知标度(0 = 黑,1 = 白),数值本身没有线性光意义;而 C 的上限随色相变化,不是固定值。这两个约束不手动盯住,哪怕 L 写对了,整体感官一致性也会在边缘设备上崩掉。


















