配了五年设计系统,每次调完色值都要靠设计稿还原——今天 CSS 用一个函数把这件事彻底原生化了
设计师在 P3 屏幕上花了两小时调一个品牌紫,导出来你发现跟你代码里的 #8b5cf6 根本不是一回事。用户用 iPhone 15 看你的页面,设计师用 MacBook Pro 调的颜色——两个设备根本不在同一个色域里。
这不是你的问题。这是 CSS 长期只能处理 sRGB 这个 35% 可见光谱的色域,而现代设计工具从第一天起就跑在 P3(45-50% 可见光谱)上的断层。
color() 函数就是来解决这个断层的。
color(display-p3):让 CSS 直接输出广色域
color() 是 CSS Color Level 4 引入的通用颜色函数,它的核心能力是指定在哪个色彩空间里解释这组数字。写法很简单:
/* 显式声明在 display-p3 色域里解释这组数字 */
.brand-purple {
color: color(display-p3 0.485 0.256 0.887);
}
/* 渐变里同理 */
.hero-gradient {
background: linear-gradient(
color(display-p3 0.9 0.2 0.1),
color(display-p3 0.2 0.5 0.95)
);
}
关键点:这里的数字是小数形式 (0.0-1.0),不是 sRGB 里的 0-255。把 sRGB 的十六进制直接扔进去,会映射到 P3 坐标系里完全不同的位置,颜色反而失真。
必须用专业工具导出真实的 P3 色值,不能靠换算。
截至 2026 年,color(display-p3) 全球覆盖率 93.54%,Chrome 111+、Firefox 113+、Safari 15+、Edge 111+ 均已支持。
Relative Color Syntax:CSS 自己会派生颜色了
color() 的另一个杀手级能力是相对颜色语法(CSS Color Level 5)。它的作用是从一个已有颜色推导出新颜色,不需要 Sass,不需要 JS:
:root {
--brand: oklch(55% 0.21 260);
}
/* 派生一个亮色变体 */
--brand-light: oklch(from var(--brand) calc(l + 0.2) c h);
/* 派生一个暗色变体 */
--brand-dark: oklch(from var(--brand) calc(l - 0.15) c h);
/* 色相旋转 180 度(互补色)*/
--brand-complement: oklch(from var(--brand) l c calc(h + 180));
/* 降低饱和度 */
--brand-muted: oklch(from var(--brand) l calc(c - 0.1) h);
这意味着设计 token 的派生逻辑可以完全在 CSS 里完成,不再需要 Sass 的 lighten()、darken(),也不需要 JS 运行时计算。浏览器兼容性:Chrome 119+、Firefox 128+、Safari 16.2+。
三个坑
坑一:色值必须用 P3 原生值,不能从 sRGB 换算
最常见的错误是把 sRGB 色值直接塞进 color(display-p3)。比如设计师的 P3 红和 sRGB 红在 P3 坐标系里根本不在同一个位置,结果偏色。必须从 Figma/Sketch 用 ColorSync 或 Photoshop 导出真实 P3 值。
坑二:非 P3 设备上会静默降级
大多数 Windows 显示器和 Android 老机型上,color(display-p3) 会静默降级到 sRGB 近似值。同样的代码,P3 屏幕看是鲜艳的紫,非 P3 屏幕看是暗淡的紫——不是 bug,是 progressive enhancement。
坑三:Chrome 在 Windows/Linux 上有限支持
截至 2026 年,Chrome 对 color(display-p3) 的 P3 支持仅在 macOS 上完整生效。用 @media (color-gamut: p3) 做条件判断:
.button { background: #8b5cf6; }
@media (color-gamut: p3) {
.button { background: color(display-p3 0.485 0.256 0.887); }
}
DevTools 验证三步
- 在 P3 设备上打开 Chrome/Safari DevTools
- 选中使用了 color(display-p3) 的元素
- Color picker 里看是否显示「Display P3」标识
三步下一步
- 查设计稿:问设计师下次出图时,有没有用 P3 色域导出
- 加渐进增强:现有 sRGB 色值上加
@media (color-gamut: p3)条件升级 - 迁移派生逻辑:把 Sass 的
lighten()/darken()替换为 CSS relative color syntax
一个设计系统和它的代码之间,隔着整个色彩空间。color() 把这个断层从工程问题降级成了配置问题——你只需要问设计师要一对 P3 色值,剩下的交给浏览器。
评论区
登录后可评论。