设计稿里那个鲜艳的红,在网页上怎么就「化」了?今天 CSS 把这件事接上了

设计稿里那个鲜艳的红,在网页上怎么就「化」了?今天 CSS 把这件事接上了。


写前端的都见过这个场景:设计师在 Figma 里选了一个特别好看的品牌橙,色值是 display-p3(1, 0.72, 0.15),你把它原封不动粘进 CSS——结果在用户屏幕上,颜色「化」了,变暗了,没那么饱和了。

这不是你的问题,是 CSS 历史上从来没有原生方式指定「我要用哪个色空间渲染这个颜色」。现在有了。

以前怎么做?

CSS 颜色统一走 sRGB 管道。不管你写 #ff6600rgb(255, 102, 0) 还是 hsl(24, 100%, 50%),浏览器一律当成 sRGB 处理。

但 sRGB 只能覆盖人眼可见光谱的大约 35%。设计师在 P3 屏幕上选的那个橙,sRGB 根本装不下。

/* 设计师给你的 P3 色值,直接写进去会怎样? */
/* 浏览器当 sRGB 解析,饱和度直接砍一截 */
--brand-orange: #e87820; /* 这已经是被砍过的 sRGB 版本了 */

解决方案?以前只能靠设计工具导出时手动转换,或者用 PostCSS 插件在构建时处理。没有运行时能力。

color() 函数:CSS Color Level 5 正式落地

CSS Color Module Level 5 给 CSS 增加了一个核心能力:指定颜色用哪个色空间渲染。核心函数是 color()

/* 直接声明这个颜色用 display-p3 色空间 */
--brand-orange: color(display-p3 1 0.72 0.15);

/* 带透明度 */
--brand-orange-80: color(display-p3 1 0.72 0.15 / 0.8);

/* 多参数混色(Firefox 150+)*/
background: color-mix(in display-p3, var(--brand) 30%, white);

支持哪些色空间?主流就这几个:

色空间 用途 浏览器支持
srgb 标准 web 色,和 hex/rgb 等价 所有
display-p3 苹果主推广色域,比 sRGB 多约 50% 颜色 Chrome 111+ / Firefox 113+ / Safari 15+
display-p3-linear display-p3 的线性光版本 Chrome 144+ / Firefox 146+ / Safari 26.2+
srgb-linear sRGB 线性光版 Chrome 111+ / Firefox 113+ / Safari 15+
oklch / oklab perceptually uniform 色空间 所有主流

其中 display-p3 是最实用的广色域选项。苹果全系设备天然支持,Windows 高端屏幕和 Android 旗舰也支持。覆盖了约 93% 的全球设备(需要屏幕本身是 P3 屏)。

display-p3-linear 和 display-p3 的区别

/* display-p3:gamma 压缩(和 sRGB 一样有人眼感知的 gamma 曲线) */
/* 适合:最终显示的颜色值 */
color(display-p3 1 0.72 0.15)

/* display-p3-linear:线性光(没有 gamma,直接物理光量) */
/* 适合:做颜色运算、混合、插值,物理正确 */
color(display-p3-linear 1 0.72 0.15)

举个例子:你在 CSS 里 color-mix(in display-p3-linear, ...) 做颜色混合,结果比 color-mix(in display-p3, ...) 物理正确;如果是 color-mix(in oklch, ...),则两者在感知上最正确。

实际工作流:怎么落地

1. 先拿到设计师的 P3 色值

Figma 支持直接导出 display-p3 色值。设计师在颜色面板里选「Display P3」,复制出来的十六进制值本质上还是 sRGB approximation(因为 Figma 剪贴板是 sRGB),但设计文件里存的是 P3。

关键动作:让设计师把 color(display-p3 1 0.72 0.15) 这种格式的色值直接给你,不是 hex。

2. CSS 写 fallback

/* 标准 sRGB fallback(所有浏览器都认) */
--brand-orange: #e87820;

@supports (color: color(display-p3 1 0 0)) {
  :root {
    /* 升级到 display-p3(只有浏览器+屏幕同时支持才生效) */
    --brand-orange: color(display-p3 1 0.72 0.15);
  }
}

3. 配合 color-gamut 检测屏幕能力

/* 另一种方式:用 media query 检测屏幕是否支持 P3 */
:root {
  --brand-orange: #e87820;
}

@media (color-gamut: p3) {
  :root {
    --brand-orange: color(display-p3 1 0.72 0.15);
  }
}

@media (color-gamut: p3)@supports 更精确——它只会在屏幕本身支持 P3 时才触发,而不是只检查浏览器是否支持该函数。

4. 真机验证

光看代码没用,必须在真机上验证:

  • MacBook Pro (M1+): 系统设置 → 显示器 → 选择「广色域 Display P3」→ Safari/Chrome 打开页面看效果
  • iPhone 12 及之后: 天然支持 P3,在 Safari 里直接看
  • Windows: 需要专业级屏幕(如 Dell UP2720Q)才看得出区别

什么时候用这个?

不是所有颜色都值得折腾 P3。只有饱和度高的红/绿/蓝/橙在 P3 屏上才明显比 sRGB 鲜艳。普通的中性灰、浅黄、白色几乎看不出区别。

实际收益场景:

  • 品牌色/主题色:Logo、强调色、主按钮,设计师最在意的地方
  • 渐变和高饱和色块:Banner、背景装饰,纯 sRGB 的渐变接缝在 P3 屏上很明显
  • 数据可视化:图表里代表「热」的颜色用 P3 会更「热」

浏览器支持现状

截至 2026 年:

  • color(display-p3 ...):Chrome 111+ / Edge 111+ / Firefox 113+ / Safari 15+,全球覆盖率约 93%
  • color(display-p3-linear ...):Chrome 144+ / Edge 144+ / Firefox 146+ / Safari 26.2+,较新
  • 屏幕本身支持 P3:苹果全系、中高端 Windows 显示器、Android 旗舰机

结论:可以在生产环境用,但必须写 sRGB fallback。不支持 P3 的浏览器/屏幕会静默回退到 sRGB 等价值,不影响功能。

下一步

  1. 找设计师要你们的品牌色里哪些用了 display-p3
  2. 审计你们的 design tokens,找出饱和度最高的 5-10 个颜色
  3. 加上 fallback,写 @supports@media (color-gamut: p3) 升级路径
  4. 在 MacBook Pro / iPhone 上截图对比,看得出来区别再推

color() 函数是 CSS Color Level 5 里最直接影响设计稿还原度的特性。以前设计师给你的「那个颜色」在网页上永远「化」了——今天 CSS 终于把它接上了。

评论区

0 条评论

登录后可评论。

阿柯·前端架构 11 阅读