oklch生成中性灰阶必须固定c和h为0,因混合时若c或h非零会引入色偏;纯白为oklch(100% 0 0)、纯黑为oklch(0% 0 0),混合需显式写出完整oklch值并用@supports外置降级。

OKLCH 生成中性灰阶必须固定 C 和 H 为 0
直接拿一个品牌色 oklch(55% 0.215 252) 和 white 混合,结果会偏紫——因为混合过程里色度(C)和色相(H)没被压制。真正无色偏的明暗变化,只发生在纯黑、纯白和它们之间的线性过渡上。而 oklch(100% 0 0) 是纯白,oklch(0% 0 0) 是纯黑,中间所有点都必须保持 C: 0、H: 0,否则哪怕 H 是 1°,也会在极低饱和下显出微弱色偏(尤其在暗部)。
-
oklch(70% 0 0)✅ 安全中性灰 -
oklch(70% 0.001 0)❌ C 超出 0 就开始引入不可控偏色 -
oklch(70% 0 1)❌ H 非 0 时,浏览器仍按 OKLCH 插值,但人眼在低亮度下对色相异常敏感
用 color-mix() 混合时不能写 white 或 black
写 color-mix(in oklch, #3a5fa8 60%, white 40%) 会报错:Invalid color space in color-mix()。浏览器不认语义化颜色名,必须显式写出完整 OKLCH 值,且两个颜色都要在同一空间内。白色不是 #ffffff,而是 oklch(100% 0 0);黑色不是 #000000,而是 oklch(0% 0 0)。
- 浅色变体(tint):
color-mix(in oklch, oklch(55.2% 0.215 252.3) 60%, oklch(100% 0 0) 40%) - 深色变体(shade):
color-mix(in oklch, oklch(55.2% 0.215 252.3) 70%, oklch(0% 0 0) 30%) - 权重加起来不必是 100%,浏览器自动归一化,但建议写满,避免误读
@supports 降级必须外置且顺序严格
OKLCH 灰阶一旦失效,不会退成灰色,而是整个声明被跳过,回退到上一条有效颜色(比如 background-color: #3a5fa8)。如果没设 fallback,按钮可能突然变成主色本体而非深色版。降级代码必须写在 @supports 块**外面且上方**,检测语句必须带单位。
- ✅ 正确结构:
button { background-color: #3a5fa8; } @supports (color: oklch(0% 0 0)) { button { background-color: oklch(40% 0 0); } } - ❌ 错误结构:
@supports (color: oklch(0 0 0))(缺%)、@supports not (color: oklch(0% 0 0))(安卓 WebView 解析失败) - 别指望 CSS 自动 fallback 到
hsl()或rgb()—— 它们根本不是中性灰生成逻辑
明度 L 的取值不是线性映射,但 OKLCH 下它就是感知线性
有人试过把 L 从 50% → 60% → 70% 均匀递增,发现视觉上 50→60 很轻微、60→70 却跳跃明显——那是 HSL 的坑。OKLCH 的 L 就是为解决这个设计的:每 +10% 的 L,在人眼看来明度提升基本一致。但要注意,L: 0% 和 L: 100% 是物理极限,中间段才真正“均匀”。低于 L: 10% 时,显示器响应非线性会重新主导,再细调 L 已无意义。
- 推荐安全区间:
L: 15%–90%,覆盖绝大多数 UI 元素的深浅需求 - 禁用态背景常用
oklch(92% 0 0),比hsl(0, 0%, 92%)更柔和、更接近真实纸张白 - 不要用 OKLCH 算深色模式的“纯黑背景”——
oklch(0% 0 0)在 OLED 屏上是真关像素,但多数 UI 需要的是oklch(3% 0 0)这类软黑,避免晕光
oklch(50% 0 0),如果显示器只接收 8bit 信号,那 50% 明度仍会被截断成 128 级中的一档——这时候,插值密度和噪点纹理比颜色函数本身更关键。前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











