广义的P3颜色可能是 "新的视网膜":一种让你的网站在现代硬件上看起来更有活力的方法。大多数新的苹果设备(和Safari)已经支持这些额外的颜色。让我们来看看如何使用SVG的P3颜色。
极短的版本
在你的文本编辑器中打开一个SVG。添加一个带有color-gamut: p3 media query的<style> 标签。用OKLCH格式的P3颜色来替换颜色。
<svg viewBox="0 0 120 120" xmlns="http://www.w3.org/2000/svg">
+ <style>
+ @media (color-gamut: p3) { rect { fill: oklch(55% 0.23 146) } }
+ </style>
<rect x="10" y="10" width="100" height="100" fill="#048c2c"/>
</svg>
一个小小的理论
屏幕只能显示人类可见的一小部分颜色。不同的屏幕可以显示不同数量的颜色。
有一些标准的颜色子集(色彩空间),为开发者创造了一些标准。其中最流行的sRGB(普通显示)是由惠普和微软在1996年开发的。Hex#048c2c,rgba(), 或hsl() 只能对这个sRGB颜色空间的颜色进行编码。
什么是P3?
许多现代屏幕可以显示比sRGB标准至少多20%的颜色。例如,大多数OLED和一些IPS屏幕可以做到这一点。
2005年,总部位于好莱坞的数字影院倡议组织用这些新的颜色创建了一个新的标准:DCI-P3色彩空间。2015年,苹果公司对其进行了一些调整,并将其称为Display P3。
绿色用P3的新颜色的数量。sRGB颜色显示为透明层,以便进行尺寸比较。
平台如何使用P3颜色?
许多安卓制造商在不改变应用程序和图像的情况下实现了新的颜色。他们只是把调色板拉长,稍微改变一下颜色,以便填满新的P3空间,使UI看起来更有活力。你可以在许多此类手机的屏幕→颜色设置中找到这一功能。
安卓做事方式背后的好处是,我们现在有了对P3的支持,而不需要改变生态系统。但这也带来了一个很大的问题--应用程序最终并不像设计师最初设想的那样。
苹果选择了另一种方式:内容创建者或应用开发者必须明确定义P3颜色。
要在一个平台上呈现P3颜色,你需要4样东西。
- 一个支持P3的屏幕。
- 一个带有支持P3的渲染引擎的操作系统。
- 浏览器(或任何其他查看器应用,如图像查看器)中的P3支持。
- 内容中的P3定义。
这就是为什么在2022年春天写这篇文章时,我们有一些支持P3的奇怪情况。例如,在MacOS上,Chrome可以从JPEG图像中渲染P3颜色,但不能从CSS中渲染。
而目前,你只能在Safari浏览器内和支持P3的现代苹果硬件上看到P3颜色。
P3有什么用?
有些人认为,P3的颜色只是简单地更鲜艳(更饱和)。但P3的好处并不限于充满活力的标志和登陆页面。
一个特定色度的OKLCH空间的切片。圆点显示的是具有不同色调、相同色度和亮度的调色板。sRGB颜色显示为透明层。
- 为设计系统提供更灵活的调色板有些sRGB颜色不会有相同明度和色度的颜色对,而是有另一种色调。有了P3,你就可以更灵活地为你的设计系统创建调色板。
一个特定色度的OKLCH色彩空间的片断。两个相邻的点具有相同的色度,但左边的点更暗。sRGB颜色显示为透明层。
- 为设计师提供更多选择对设计师来说,更多的颜色总是更好的(试想一下,如果有人拿走了你目前供应的25%的sRGB颜色)。例如,在sRGB中,如果不改变色度值,你就不能使
#048c2c颜色变深,但在P3中,你有这个选项。
为什么OKLCH是P3的最佳格式?
十六进制颜色格式、rgba() ,以及hsla() 只能定义sRGB颜色。因此,我们需要另一种颜色格式来定义P3的颜色。
在CSS中,我们有color(display-p3 1 0.5 0) 格式,它在概念上与rgba() (你定义颜色的红、绿、蓝成分)很接近。
但是我们推荐OKLCH格式oklch(55.74% 0.169 146) 。这对网络生态系统来说是一个很好的机会,可以向更好的格式发展,在其他领域也会很有用。
- OKLCH支持P3以上的颜色。我们已经有了Rec.2020色彩空间标准。而OKLCH使用Oklab色彩空间,它可以支持任何颜色。
- 它类似于HSL:不使用红、绿、蓝这样的硬件成分,而是使用亮度、色度、色调,这更容易被人类理解。
- 人眼看到的是不同色调的不同数量的颜色。HSL通过对颜色空间的变形来掩盖这种复杂性。但是,变形的空间导致了颜色转换后不可预测的结果。例如,对亮度的改变会因色调的不同而产生不同的结果(导致a11y问题)。相比之下,OKLCH没有对色彩空间进行变形,并且在色彩转换后有可预测的结果。
- LCH和Lab与OKLCH非常相似,但它们有一个问题:色度变化时的色调变化。OKLCH就是为了解决这个问题而产生的。
如何在CSS中使用P3
我们不能在没有退路的情况下在CSS中使用OKLCH。这是因为只有Safari提供对oklch() 的支持。对于Web应用程序来说,这是一个很好的polyfill。
对于P3颜色来说,使用oklch() 是比较麻烦的。如果一个使用sRGB硬件的浏览器试图渲染一个P3颜色,它将试图找到最接近的sRGB颜色。问题是,我们有许多不同的算法来处理这种颜色箝制。目前还没有标准,我们在不同的平台上可能会出现意想不到的结果。
就目前而言,最好是定义一个sRGB回退。
你可以通过使用color-gamut: p3 media query来检测P3的硬件支持。
.block {
background: #048c2c;
}
@media (color-gamut: p3) {
.block {
background: oklch(55% 0.23 146);
}
}
这里有一个好处:没有多少支持P3的浏览器版本缺乏OKLCH支持,这意味着你只需要定义一个媒体查询。
如何在SVG中添加带有P3颜色的CSS
SVG是一种类似于HTML的文本格式;相应地,你可以在文本编辑器中打开它。
你可以在SVG标签中直接使用oklch() ,但我们并不推荐这样做:目前,只有Safari提供对oklch() 。
SVG也支持CSS和媒体查询。你可以添加<style> ,并重新定义标签的属性,如fill 。
<svg viewBox="0 0 120 120" xmlns="http://www.w3.org/2000/svg">
<style>
@media (color-gamut: p3) {
rect {
fill: oklch(55% 0.23 146)
}
}
</style>
<rect x="10" y="10" width="100" height="100" fill="#048c2c"/>
</svg>
如果你有很多SVG标签,你可以给它们添加id ,以便在CSS选择器中使用。
<svg viewBox="0 0 120 120" xmlns="http://www.w3.org/2000/svg">
<style>
@media (color-gamut: p3) {
#left {
fill: oklch(55% 0.23 146)
}
#right {
fill: oklch(55.74% 0.26 259)
}
}
</style>
<rect id="left" x="10" y="10" width="45" height="100" fill="#048c2c"/>
<rect id="right" x="55" y="10" width="100" height="100" fill="#306fd4"/>
</svg>
对于梯度,你需要定义另一个梯度,并在媒体查询中替换它。
<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg">
<style>
@media (color-gamut: p3) {
circle {
fill: url(#gradient-p3)
}
}
</style>
<defs>
<linearGradient id="gradient-srgb" x1="20" y1="108" x2="106" y2="18">
<stop stop-color="#AA81F3"/>
<stop offset="1" stop-color="#E47A38"/>
</linearGradient>
<linearGradient id="gradient-p3" x1="20" y1="108" x2="106" y2="18">
<stop stop-color="oklch(70% 0.21 304.5)"/>
<stop offset="1" stop-color="oklch(70% 0.21 49.1)"/>
</linearGradient>
</defs>
<circle cx="64" cy="64" r="64" fill="url(#gradient-srgb)"/>
</svg>
不要忘记事后使用SVGO来最小化SVG源。
进一步阅读
- OKLCH选色器和转换器,可用于比较P3和sRGB颜色。
- 苹果公司关于P3的文章
- Oklab色彩空间介绍


