新颜色函数如color-mix()、oklch()、color-contrast()在旧浏览器中静默失效,需用广泛支持的格式(如#rrggbb、rgb())作fallback并置于@supports外;检测须用color: oklch(0% 0 0)等空间语法,且输入颜色必须同属一个色彩空间。

新颜色函数(如 color-mix()、oklch()、color-contrast())在旧浏览器中不会报错,而是静默失效——你写的样式直接被跳过,回退到上一条有效的声明。所以“优雅降级”的核心不是兜底逻辑多聪明,而是确保 fallback 颜色一定生效。
@supports 检测必须用 color: 基础值,不能用 color-mix
很多人想检测 color-mix() 本身是否可用,写成 @supports (color-mix: oklch(0% 0 0) 50%, red),这在 Safari 16.4 之前完全无效——浏览器根本不认识这个特性查询,整块规则被忽略。
- 正确做法是检测色彩空间是否被支持:
@supports (color: oklch(0% 0 0))或@supports (color: lch(0% 0 0)) -
@supports (color: oklab(0 0 0))当前(2026 年中)在绝大多数浏览器里仍返回false,别拿它当兜底依据 - 检测
color-contrast()要带完整语法:@supports (color: color-contrast(#000 vs #fff to WCAG20/AA)),缺参数或写错格式都会失败
fallback 颜色必须写在 @supports 外部,且顺序不能反
CSS 是从上到下解析的。如果把 @supports 块写在前面,某些早期 Chromium(如 Chrome 111 之前)会忽略后续的普通声明,最终没颜色可显示。
- ✅ 正确顺序:
background-color: #4a5568;(fallback)→ 再写@supports (...) { background-color: color-mix(...) } - ❌ 错误顺序:
@supports (...) { background-color: color-mix(...) }→ 后面再写 fallback,部分浏览器可能不读取 - fallback 只能用广泛支持的格式:
#rrggbb、rgb()、hsl()、命名色;不能用oklch()或color-mix()的输出作为 fallback
color-mix() 必须显式声明 in srgb / in oklch,且混合空间要一致
color-mix() 不写色彩空间时,部分浏览器(尤其是 Safari)会静默失败,而不是默认 fallback 到 sRGB。
立即学习“前端免费学习笔记(深入)”;
- 写
color-mix(in oklch, oklch(60% 0.2 240), oklch(40% 0.3 300))是安全的;但color-mix(oklch(60% 0.2 240), red)就不行——red 是 sRGB 值,空间不一致导致整个函数被忽略 - 权重总和不必为 100%,浏览器会自动归一化,但输入颜色必须同属一个空间
- 不要指望
color-mix(in srgb, var(--accent) 70%, transparent 30%)在深色背景上还好看——透明色混合受父背景影响极大,真要适配深色模式,得明确写color-mix(in srgb, var(--accent) 70%, #1e1e1e 30%)
color-contrast() 没 fallback 就等于没文字
color-contrast() 在不支持的浏览器里不会退到列表里的第一个候选色,而是直接跳过整条声明。如果你只写了 color: color-contrast(...),旧浏览器里文字就是继承色或初始色(通常是黑色),极可能和背景撞色而不可读。
- 必须搭配
@supportsnot或外部 fallback:color: #000;→@supports (color: color-contrast(...)) { color: color-contrast(...) } - 别依赖它做关键可访问性保障:它的对比度算法和 WCAG 实际计算方式不一致,也不处理半透层叠加场景
- WCAG 级别要写全:
to WCAG20/AA,不能简写成to AA,否则检测失败
最容易被忽略的一点:所有这些新函数的输出值都是 sRGB,但输入空间不一致就会让整条声明失效——不是渐进增强,是全有或全无。所以检测、顺序、空间一致性,三者缺一不可。


















