OKLCH 详解:终于和人眼感知一致的颜色格式
OKLCH 用三个维度描述颜色:看起来有多亮、有多鲜艳、属于哪个色相。和 HSL 不同,同一个亮度值在任何色相下看起来都一样亮,所以调色板、悬停状态和无障碍对比度都变得可预测。
阅读约 1 分钟
OKLCH 是什么
OKLCH 是 Oklab 的极坐标形式。Oklab 是 Björn Ottosson 在 2020 年发布的感知均匀色彩空间。OKLCH 由三个数值组成:L 是感知亮度,从 0(黑)到 1 或 100%(白);C 是色度,即颜色的浓淡,从 0(灰)到屏幕能显示的最鲜艳颜色的约 0.37;H 是色相角,从 0 到 360 度。
同一个颜色用不同格式写出来是下面这样。所有数值都由 PickShade 实时计算,可以直接复制使用。
| 格式 | 值 |
|---|---|
| HEX | |
| RGB | |
| HSL | |
| OKLCH | |
| OKLab |
为什么 OKLCH 比 HSL 好
HSL 的亮度只是一个公式,并不代表人眼的感受。hsl(60 100% 50%) 是明亮的黄色,hsl(240 100% 50%) 是深蓝色,两者的亮度却都是 50%。用 HSL 做调色板,每个色相都得手动修正。
在 OKLCH 中,L 相同的颜色看起来就是一样亮。保持 L 和 C 不变、只旋转 H,就能得到一组视觉上均衡的色相;保持 H 和 C 不变、逐级调整 L,就能得到干净的色阶。这也是 Tailwind CSS v4 用 OKLCH 定义整套默认调色板的原因。
亮度还能用来预判对比度。文字和背景的 L 相差约 0.4 以上时,通常就足够易读,挑选无障碍配色时思路会清晰很多。
CSS 语法
亮度可以写成百分比,也可以写成 0 到 1 之间的数字。色度是一个数字。色相是以度为单位的角度。透明度写在斜杠后面。
CSS
color: oklch(62.8% 0.258 29.23);
background: oklch(0.7 0.15 250 / 50%);
border-color: oklch(from var(--brand) calc(l - 0.1) c h);浏览器兼容性
所有主流浏览器的当前版本都支持 oklch():Safari 15.4 起,Chrome 和 Edge 111 起,Firefox 113 起,覆盖了远超 90% 的用户。如果要兼容很老的浏览器,在 OKLCH 值的上一行写一个 HEX 回退值即可。
CSS
color: #ff5733;
color: oklch(68% 0.21 33.7);色度上限与色域
OKLCH 能描述任何屏幕都显示不了的颜色。色度的上限取决于亮度和色相:鲜艳的黄色只在高亮度附近存在,鲜艳的蓝色只在低亮度附近存在。当数值超出 sRGB 或 Display P3 色域时,浏览器会把它映射回色域内,颜色可能因此发生偏移。
PickShade 会标出超出 sRGB 的颜色,并给出最接近的可显示颜色:保持亮度和色相不变,只降低色度,这正是 CSS Color 4 推荐的方法。
如何把 HEX 转换为 OKLCH
转换步骤是:HEX 转 sRGB,sRGB 转线性光,线性 sRGB 转 LMS 视锥空间,取立方根,再用矩阵转到 Oklab,最后把 Oklab 转成极坐标。手算很容易出错,把颜色粘贴到转换器里,直接复制结果就行。
常见问题
所有浏览器都支持 OKLCH 吗?
是的,所有主流浏览器的当前版本都支持:Safari 15.4 及以上,Chrome 和 Edge 111 及以上,Firefox 113 及以上。如果必须兼容旧浏览器,在它前面加一行 HEX 即可。
OKLCH 和 LCH 有什么区别?
两者都用亮度、色度和色相描述颜色。CSS 的 lch() 基于 CIELAB,调整亮度时蓝色会偏向紫色。OKLCH 基于 Oklab,色相更稳定,所以蓝色的色阶始终是蓝色。
为什么我的 OKLCH 颜色和输入的不一样?
很可能是色度超出了屏幕在该亮度和色相下能显示的范围,浏览器把它映射到了显示器的色域内。降低色度,直到 PickShade 不再提示超出色域为止。
Tailwind CSS 能用 OKLCH 吗?
可以。Tailwind CSS v4 的默认调色板本身就是用 OKLCH 定义的,在 @theme 中也可以直接用 OKLCH 写自定义颜色。