设计师给你一个 Display P3 色值,旧浏览器根本显示不出来——今天 color() 把这件事彻底原生化了
设计师给你一个颜色,说这是 Display P3 的,要用在 logo 上。你写进 CSS,Chrome 对了,Safari 也对了,但用户的旧 Chrome 显示出来偏了。
以前这个问题的解法是:找工具把 Display P3 转成 sRGB,算出一个近似值写进 CSS。运气好差得不多,运气不好你得配两套。今天 color() 把这件事彻底原生化了——一条 CSS 同时搞定 Display P3 显示和 sRGB fallback。
color() 的基本语法
color() 来自 CSS Color Level 5,允许你直接指定任意颜色空间:
/* 直接写 Display P3 颜色 */
.logo {
background-color: color(display-p3 1 0.5 0);
}
/* 加透明度 */
.overlay {
background-color: color(display-p3 1 0.5 0 / 0.8);
}
/* 支持的颜色空间 */
color(srgb 1 0 0); /* 标准 RGB */
color(display-p3 1 0 0); /* 苹果主推的广色域 */
color(prophoto-rgb 0.8 0.1 0.05); /* 照片级广色域 */
color(xyz-d65 0.41 0.21 0.09); /* CIE XYZ 绝对色域 */
这解决了第一个问题:设计师给你的 Display P3 值,原样写进 CSS,现代浏览器直接显示正确颜色。
相对颜色语法——从主色自动派生全家桶
真正值钱的在后面。color() 支持相对颜色语法,格式是 color(from <origin> <colorspace> c1 c2 c3 / A):
/* 以 --primary 为起点,输出 sRGB 系的同色系 */
.button {
--primary: color(display-p3 0.85 0.2 0.35);
background-color: var(--primary);
/* 暗色版本 */
background-color: color(from var(--primary) srgb 0.7 0.1 0.2);
/* 亮色版本 */
background-color: color(from var(--primary) srgb 1.2 1.2 1.2);
/* 加透明 */
background-color: color(from var(--primary) srgb r g b / 0.5);
}
这里的 r、g、b 是从原始颜色提取的通道值,可以在输出时重新组合、计算。OKLCH 空间下做明度调整最精准:
:root {
--brand: oklch(55% 0.2 240);
/* 浅色变体 */
--brand-light: color(from var(--brand) oklch calc(l + 30%) c h);
/* 暗色变体 */
--brand-dark: color(from var(--brand) oklch calc(l - 20%) c h);
/* 饱和度加倍 */
--brand-saturated: color(from var(--brand) oklch l calc(c * 2) h);
}
以前做设计系统色阶:设计师给主色,工程师用工具算出 n 个变体,每次改主色要全部重新算。现在主色改一个值,所有变体自动更新。
自动 fallback——旧浏览器也有得看
color() 的另一个价值在于渐进增强语义:
.card {
/* 现代浏览器显示 Display P3 广色域 */
background-color: color(display-p3 0.92 0.45 0.38);
/* 旧浏览器 fallback——写在前面的普通 sRGB 声明 */
background-color: #EB7342;
}
旧浏览器不认识 color(),直接忽略,然后用前面的 #EB7342。Chrome 98+ / Safari 15.1+ / Firefox 113+ 支持 color()。主流移动端浏览器全部支持,Safari iOS 15 之后完全覆盖。
完整实战:设计系统色阶自动派生
用一个实际场景把上面的能力串起来。假设设计系统主色是 Display P3,我们需要派生一套完整的色阶:
:root {
/* 主色——设计师给的 Display P3 值 */
--color-primary: color(display-p3 0.72 0.15 0.88);
/* 10 阶明度色阶 */
--color-50: color(from var(--color-primary) srgb calc(r * 1.1 + 0.1) calc(g * 1.1 + 0.1) calc(b * 1.1 + 0.1));
--color-100: color(from var(--color-primary) srgb calc(r * 1.05 + 0.05) calc(g * 1.05 + 0.05) calc(b * 1.05 + 0.05));
--color-500: var(--color-primary);
--color-900: color(from var(--color-primary) srgb calc(r * 0.6) calc(g * 0.6) calc(b * 0.6));
/* 语义色:hover / active / disabled */
--color-primary-hover: color(from var(--color-primary) srgb r g calc(b * 0.8));
--color-primary-active: color(from var(--color-primary) srgb calc(r * 0.85) calc(g * 0.85) calc(b * 0.85));
--color-primary-muted: color(from var(--color-primary) srgb r g b / 0.15);
/* 对应主题变量 */
--surface-primary: var(--color-primary);
--text-primary: color(from var(--color-primary) srgb 1 1 1 / calc(1 - l));
}
.btn-primary {
background-color: var(--surface-primary);
color: var(--text-primary);
}
.btn-primary:hover {
background-color: var(--color-primary-hover);
}
改一处主色,整个系统的颜色变体全部自动更新。这是以前 Sass / PostCSS / JS 工具才能做到的事情,现在纯 CSS 原生支持。
下一步:把这三件事用起来
第一,你现在就可以把设计师给的 Display P3 值写进 color(),不需要任何工具。
第二,把设计系统里的颜色变量改成相对颜色语法,主色一变,全部变体自动更新。
第三,如果你的项目还在用旧版浏览器,用 CSS 层叠让 color() 和普通色值共存:新浏览器用广色域,旧浏览器用 sRGB fallback,渐进增强零成本。
color() 是 CSS 颜色系统的补完——从 rgb() hsl() 到 oklch(),再到 color(),终于把「指定颜色空间」这件事原生化了。设计师给你的 P3 色值,不需要转,不需要工具,直接写进去就行。
评论区
登录后可评论。