你以为设计软件里调的色,CSS 都接得住?今天 color() 把这件事彻底原生化了
你以为设计软件里调的色,CSS 都接得住?今天 color() 把这件事彻底原生化了
配了三年设计系统,今天切到深色模式给品牌色加透明度时,发现 sRGB 色域根本装不下那抹荧光绿——设计稿上明明是 #00FF87,上屏却暗淡了 30%。这不是你色感出了问题,是 CSS 底层从来就没支持过那块屏幕能显示的颜色。
CSS 颜色长期活在 1996 年的色域里。
sRGB 是 1996 年定稿的标准,当年连 LCD 屏幕都没普及,它的色域只能覆盖人眼可见光的大约 35%。而 2016 年以后的 iPhone、MacBook Pro、高端 Android 旗舰,屏幕已经支持 Display P3——能多显示约 45% 的色彩容量。那些在 Figma 里调出来、你亲眼在 MacBook 上看着”就是这色”的荧光绿、烈焰红、电光蓝,上到用户手机上一看,暗了。
CSS Color Module Level 4 把这件事彻底翻了。核心就是这个 color() 函数,让 CSS 直接在 display-p3、rec2020、xyz-d50 这些色彩空间里指定颜色,而不是只绑死在 sRGB。
color() 怎么写
绝对值语法:
/* 纯 display-p3 声明,饱和红 */
.vivid-red {
background-color: color(display-p3 1 0 0);
}
/* 带透明通道,75% 不透明度蓝 */
.electric-blue {
background-color: color(display-p3 0.2 0.6 1 / 0.75);
}
/* sRGB 显式声明,和 rgb(0 120 255) 等价但语义更清晰 */
.explicit-srgb {
color: color(srgb 0 0.47 1);
}
相对值语法(CSS Color Level 5):
/* 从已有颜色派生,在 display-p3 空间里降明度 */
.button-primary {
background-color: var(--brand);
background-color: color(from var(--brand) display-p3 calc(l * 0.8) c h);
}
color() 支持的色彩空间:srgb、srgb-linear、display-p3、a98-rgb、prophoto-rgb、rec2020、xyz、xyz-d50、xyz-d65。display-p3 是目前最实用的广色域空间,覆盖苹果全系屏幕和大多数高端 Android 设备。
实际效果差异有多大
来看一个真实案例。根据 ColorUI.io 的色板工具,同样的紫色 #7C5CFF:
/* sRGB 版本 */
.brand {
color: #7C5CFF;
color: color(display-p3 0.467 0.366 0.965);
}
在 sRGB 屏幕上看,两行完全一致;在支持 Display P3 的 iPhone 14 Pro 上,第二行明显更亮、更饱和、更有”荧光感”。这就是 45% 色彩容量差异的实际观感。
品牌色、UI 强调色、图标色、渐变色 是 display-p3 最有价值的场景。想让按钮的悬停态比默认状态更抢眼、想让导航栏的背景色在 OLED 屏幕上真正”发光”——sRGB 给不了你的,display-p3 可以。
渐进增强:保底写法
color() 强的地方在于可以无缝渐进增强。先写 sRGB 保底,再叠 display-p3:
.call-to-action {
/* 所有浏览器都认识这个 */
background-color: rgb(255 64 85);
/* 只有 P3 屏幕才渲染更饱和的版本 */
background-color: color(display-p3 0.98 0.21 0.31);
}
不放心就加 @supports:
@supports (color: color(display-p3 1 0 0)) {
.brand-accent {
background-color: color(display-p3 0.98 0.21 0.31);
}
}
想精准检测设备屏幕能力,用 @media 查询:
@media (color-gamut: p3) {
.brand-accent {
background-color: color(display-p3 0.98 0.21 0.31);
}
}
注意:color-gamut: p3 检测的是浏览器是否支持 P3,不是屏幕物理上能不能显示。safari 用户基本都支持;Firefox 113+、Chrome 111+ 都支持。caniuse 数据全球覆盖率 93.54%。
三个坑
坑一:超出设备色域的颜色会被自动映射。 你写 color(display-p3 0 1 0) 写的是纯绿,在 sRGB 屏幕上看,浏览器会把颜色”压”到屏幕能显示的范围,不报错但观感打折扣。所以 sRGB fallback 必须保留。
坑二:P3 颜色可能改变对比度。 一块在 sRGB 下对比度 4.5:1 的绿色,在 display-p3 里明度通道变了,对比比可能降到 3.8:1。WCAG AA 要求正文 4.5:1、背景大字 3:1——上了 P3 要重新测。coloriui.io 的色板工具可以快速测两套色域的对比度。
坑三:不是所有设计工具都默认导出 P3。 Figma 里要手动把文档色彩配置切到 Display P3,导出的 CSS 才包含 display-p3 色值。如果你的设计系统还是 sRGB 导出,color() 的效果等于 0。
三步下一步
第一步:审计品牌色板。 用 coloriui.io/p3 扫描你的 CSS 色值,找出 P3 覆盖面积最大的颜色——通常是高饱和度的强调色和图标色,优先这几颗动手。
第二步:加 fallback 叠写。 品牌色变量里,hex/rgb() 放第一行保底,display-p3 放第二行增强,别删第一行。
第三步:测两套屏幕。 有条件的话,拿一台支持 P3 的 Mac 和一台普通 sRGB 显示器对照看。颜色差异最明显的就是你该优先改的那几颗。
color() 不是”又一个新颜色写法”,它是 CSS 第一次承认:屏幕能显示的颜色,比 sRGB 大得多。设计师在 Figma 里调的色,CSS 终于接得住了。
评论区
登录后可评论。