移动端推荐用oklch(),因其L值基于CIE 2002感知模型,在高DPI、多色域设备上保障可读性与一致性;但必须严格带%单位、降级写在@supports外上方、色相差超180°需手动拆段。

移动端开发推荐用 oklch(),不是因为它“新”,而是它在小屏、高DPI、多色域设备上能真正守住可读性、一致性与无障碍对比度——但前提是单位写对、降级写稳、色相边界拆开。
移动端屏幕亮度和色域差异大,oklch() 的 L 值才真正反映人眼感知
手机屏幕白点、gamma、P3 色域覆盖率差异极大,hsl() 的 L 是 RGB 极值平均,同一 hsl(240, 100%, 50%) 在 iPhone 15 Pro(P3)和旧安卓(sRGB)上亮度感知能差 40%;而 oklch(54% 0.32 240) 的 L 来自 CIE 2002 模型,在不同设备上更接近“人眼看多亮”。
-
L必须带%:写成oklch(54 0.32 240)会被所有主流移动端浏览器(包括 Safari 17.4+、Chrome for Android 112+)静默忽略 -
C要控制在 ≤0.28:超出后在 sRGB 屏幕上会裁剪发灰,尤其蓝紫区;P3 屏虽能显示,但 Web 内容默认走 sRGB 渲染管线 - 深色模式切换时,只改
L:比如oklch(62% 0.28 258.5)→oklch(38% 0.28 258.5),文字在浅底/深底上对比度变化平滑,不会像hsl()那样一调就发青或发紫
@supports 降级结构在 WebView 中极易失效
安卓 WebView(尤其 Android 12–14 系统自带)对 @supports 解析有 bug:@supports not (color: oklch(0% 0 0)) 会被整块跳过;@supports (color: oklch(0 0 0))(缺 %)返回 false;连 oklab() 检测都始终为 false。
- 降级色必须写在
@supports块**外部且上方**:background-color: #2563eb;→ 再写@supports (color: oklch(0% 0 0)) { ... } - 检测值必须带单位:
@supports (color: oklch(0% 0 0))✅,@supports (color: oklch(0 0 0))❌ - 别依赖 PostCSS 自动 fallback:Tailwind v4 默认不插件补降级,需手动加
@csstools/postcss-oklab-function并设preserve: true
渐变和悬停态在小屏上更易暴露插值断层
移动端用户常做长按、滑动、悬停模拟,linear-gradient() 和 transition 若没处理好,会立刻暴露色彩空间混用问题。
立即学习“前端免费学习笔记(深入)”;
-
linear-gradient()里写oklch()≠ OKLCH 插值:目前所有浏览器仍强制 sRGB 插值,想保感知均匀,只能靠多停靠点逼近,例如:linear-gradient(oklch(0.62 0.28 258.5) 0%, oklch(0.68 0.27 259) 45%, oklch(0.75 0.28 258.5) 100%) - 色相跨 0° 边界(如 350° → 10°)必须手动拆段:
linear-gradient(oklch(0.7 0.25 350), oklch(0.7 0.25 0), oklch(0.7 0.25 10)),否则中间出现灰紫色带,在 OLED 小屏上极其刺眼 -
transition中混用oklch()和hsl():哪怕只有一处,整条动画 fallback 到 sRGB,中间帧发灰——全链路必须统一色彩空间
最常被忽略的不是“怎么写”,而是“在哪写错”:L 缺 %、fallback 顺序颠倒、色相差超 180° 没拆段——这三处任一出错,移动端 UI 就可能在某台机器上突然变黑、变透明、或文字不可读,而且 DevTools 里完全看不出问题。


















