OKLCH渐变不发灰的关键在于绕开sRGB插值,唯一纯CSS方式是color-mix(in oklch,...),需两端均为oklch、显式加权、停靠点间隔≤20%且避免混用rgba或简写。

OKLCH 渐变中间不发灰,不是因为它“自动避开了灰色”,而是你没让浏览器走 sRGB 插值那条老路——只要满足三个硬条件,它压根就不经过那个会发灰的数学过程。
color-mix(in oklch, ...) 是唯一真正绕开 sRGB 插值的纯 CSS 方式
linear-gradient() 无论写多少个 oklch(),浏览器仍会转成 RGB 再插值,中间那段灰是算出来的,躲不掉。但 color-mix() 不同:它在声明解析阶段就完成静态混合,不依赖运行时渐变引擎。
- 必须两端都是
oklch()格式,混一个rgb()或#fff就静默失效 - Chrome 112+、Safari 17.5+ 支持,Firefox 尚未实现,别用
@supports (background: linear-gradient(in oklch))检测 - 不能只写起点终点,得显式加权,例如
color-mix(in oklch, oklch(60% 0.28 240) 70%, oklch(90% 0.28 240) 30%)
停靠点间隔 ≤20% 才能封住浏览器的 sRGB 补间漏洞
就算你用 color-mix() 算出了一组 OKLCH 停靠点,最终还得喂给 linear-gradient() 渲染。而浏览器对两个相邻色标之间,依然用 sRGB 插值——跨度越大,中间越容易塌进灰区。
- 蓝→黄这类色相翻转路径,视觉敏感区集中在 40%–60%,必须拆成至少三段:0%、45%、100%
- 别信“数值中点=视觉中点”,用 Björn’s OKLCH Picker 或
culori采样,导出带百分比的rgb()列表再拼 - 移动端 iOS Safari 对浅色过渡(如
#fff9cc → #ffffff)也极敏感,哪怕无 alpha,也要加 1–2 个中间点
rgba() + OKLCH 混用会直接触发 sRGB 降级
很多人以为“用了 oklch 就安全了”,结果在渐变里塞了一个 rgba(0,0,255,0.8),整条链路立刻 fallback 到 sRGB——不是报错,是静默退化,DevTools 里 computed color 全是 rgb()。
立即学习“前端免费学习笔记(深入)”;
- 禁用
background简写,它会把oklch()转成 RGB 缓存,失去意义;必须拆成background-color+background-image - 透明渐变别靠
rgba(),设死容器底色(如background-color: #fff),再用background-image: linear-gradient()叠纯色 - 深色模式切换时,如果
--primary是oklch(),但--primary-hover是hsl(),transition 过程中必先灰一下再显色
真正难的不是写出 oklch(60% 0.28 240),而是意识到:你写的每一条颜色声明,都在悄悄选择一种人眼看不见的数学坐标系;而灰,只是那个旧坐标系给出的标准答案。


















