在学习Claude Design 系统提示词时看到设计时使用“oklch 定义”,由于先前没有接触过,特整理相关的资料。

什么是 OKLCH?

OKLCH 是 Oklab 色彩空间的圆柱坐标(极坐标)形式,三个字母分别代表:Lightness 明度、Chroma 彩度、Hue 色相。它属于 CSS Color Level 4 规范,是现代网页表达颜色的新标准之一。

  • L (Lightness, 感知亮度):范围 0% (黑) 到 100% (白)。它是感知亮度,和色相无关。这是OKLCH最核心的改进,它直接对应人眼感知的明亮程度。这是 OKLCH 最大的卖点。
  • C (Chroma, 彩度):从 0 (纯灰) 到最大值 (色彩饱和度)。在CSS中,100% 的色度对应数值4(理论无上限,但超过设备能力会被裁剪)。类似「饱和度」,但更准确的感知度量。注意:不同色相能到达的最大 C 不同。
  • H (Hue, 色相):0°到 360°的角度,决定了是红、绿还是蓝等具体颜色。0° 对应紫红色,90° 对应黄色,180° 对应蓝绿色,270° 对应天蓝色。角度间隔在感知上是均匀的,不像 HSL 那样「挤」在某些色段。

OKLCH核心优势在于感知均匀性(Perceptually Uniform)。简单来说,它能让颜色的数值变化与我们的视觉感受保持一致,从而让设计师和开发者能更精确、更可预测地控制颜色。

如果把所有可能颜色画成一个三维形状:竖直轴是明度 L(底黑顶白),到中轴的半径是彩度 C(越往外越艳),绕轴的角度是色相 H(一圈 360°)。它不是一个规整的圆柱——因为不同色相在同样的明度下能到达的最大彩度不同,所以边界像「高低错落的山峰」。顶部是一个色相环。

OKLCH的产生背景

痛点一:HSL 的「明度」名不副实

下面两行色块,第一行用 HSL、第二行用 OKLCH,各自的「明度」参数完全相同。请观察黄色与蓝色:

痛点二:sRGB / HEX 色域太窄

我们熟悉的 #RRGGBB、rgb()、hsl() 全部被限制在sRGB 色彩空间内,而 sRGB 只能覆盖人眼可见光谱的大约 35%。如今 iPhone、MacBook、大量 OLED 显示器都支持更广的Display P3 色域(多约 50% 的颜色),用旧写法等于主动放弃了屏幕上那批更鲜艳的颜色。

痛点三:渐变插值会「发灰发脏」

默认情况下,CSS 渐变是在 sRGB 空间里做线性插值的。从红到蓝,中间会经过一段低饱和的灰紫色「死区」。改用 OKLCH 插值后,渐变会沿着感知上更自然的路径走,颜色始终饱满。这一点在第 05 节有实地对比。

OKLCH的核心优势

感知均匀:调色板「间距」可预测

在 OKLCH 中,把 L 每次减小相同数值,亮度的变化在人眼看来是均匀的;把 C 每次减小相同数值,「鲜艳程度」的变化也是均匀的。这正是构建一套「步骤感一致」的调色板(如 50–950 色阶)的法宝。Tailwind CSS v4 已经把整套默认色板用 OKLCH 重建,所以 bg-blue-500 和 bg-yellow-500 终于像「一家人」。

广色域:能描述 P3 / Rec.2020 的颜色

下面的极坐标图,是固定明度 L=0.7 时,每个色相能到达的最大彩度边界(基于真实 sRGB ↔ Oklab 转换计算得出)。外圈(青色)是 Display P3 的边界,内圈(紫色)是 sRGB 的边界——P3 明显更大,意味着它能呈现更鲜艳的颜色。OKLCH 用同一套坐标就能描述这些更广的色域,无需换语法。

更漂亮的渐变:别忘了写 in oklch

即便端点用 OKLCH 书写,渐变默认仍按 sRGB 插值。必须显式声明插值空间,才能拿到感知均匀的渐变:

无障碍友好:对比度可预测

因为 OKLCH 的明度是感知亮度,当你把文字放在 L=0.95 背景、L=0.20 前景时,你事先就知道大概的对比度,不必反复试错。固定色相与彩度、只移动明度来生成深浅色阶,调色板天然满足 WCAG 对比度要求的概率更高。

实战技巧:想给某个品牌色找「对比度达标」的文字色?把品牌色的 H 和 C 锁住,只上下移动 L,就能得到既保持品牌调性、又满足 AA/AAA 的文字颜色。

与其他色彩模型对比

维度 HEX / RGB HSL / HSV LAB / LCH OKLCH
是否设备相关 是(sRGB) 是(sRGB)
感知均匀 否(明度失真) 较均匀 是(更优色相均匀)
支持广色域
直觉性 差(人难读) 一般 好(同 HSL 习惯)
渐变更自然 较好 最好
典型语法 #3b82f6 hsl(217 91% 60%) lch(62% 0.19 259) oklch(0.62 0.19 259)

OKLCH 可以理解为「LCH 的修正版」:它保留了 LCH「明度/彩度/色相」的易用结构,但在色相均匀性(尤其蓝—紫段)和整体感知一致性上做了改进。

浏览器支持

自 2022–2023 年起,主流浏览器已全部支持 oklch()。截至 2025 年,全球约 95%+ 的用户已可正常渲染。

老浏览器兜底:不支持oklch() 的浏览器会直接忽略该声明。因此最稳妥的写法是「先写 HEX/RGB 兜底色,再写 OKLCH」——支持的用新色,不支持的回退到旧色,两者视觉接近即可。

OKLCH CSS 实战用法

基础写法

/* L 可用 0–1 或 0%–100%;C 通常写 0–0.4 的小数;H 为角度 */
.brand { color: oklch(0.62 0.19 259); }
.brand2{ color: oklch(62% 0.19 259); } /* 等价 */

感知均匀的渐变(关键:in oklch)

.banner{
  background: linear-gradient(in oklch, oklch(0.75 0.15 30), oklch(0.55 0.15 280));
}

用 color-mix() 混合(指定空间)

.btn{
  --brand: oklch(0.62 0.19 259);
  background: color-mix(in oklch, var(--brand), white 18%);
}

相对颜色语法(Relative Color):派生深浅色

.card{
  --brand: oklch(0.62 0.19 259);
  background: oklch(from var(--brand) l c h / 0.12); /* 同色相/彩度,仅改透明度 */
}
.card-strong{
  background: oklch(from var(--brand) calc(l - 0.25) c h); /* 压暗 0.25 */
}

广色域增强(P3 屏幕更鲜艳)

.cta{
  background: oklch(0.62 0.19 259);          /* 通用,落在 sRGB 内 */
}
@media (color-gamut: p3) {
  .cta{ background: oklch(0.62 0.23 259); }   /* 广色域屏上更艳 */
}

老浏览器回退

.safe{
  background: #3b82f6;                 /* 兜底:所有浏览器 */
  background: oklch(0.62 0.19 259);    /* 支持的浏览器覆盖上方 */
}
/* 或更精确地检测 */
@supports (color: oklch(0.5 0.1 250)) {
  .modern { color: oklch(0.62 0.19 259); }
}

从 HSL / HEX 迁移的 5 条建议

  • 别逐值翻译。把 HEX/HSL 品牌色直接换算成 OKLCH 数值会丢失感知优势。应取一个基准H 与 C,再用感知属性重建整套色阶。
  • L 用小数更清爽。7 与70% 等价,但统一用小数让设计令牌更易扫描比对。
  • 注意每个色相的彩度上限不同。黄、绿能到达的最大彩度比红、紫低;若某色「怎么调都不艳」,可能是要的彩度超过了该色相的色域。
  • 切换后复核 WCAG 对比度。对比度仍在 sRGB 下计算,迁移后务必重新核对文字/背景配对。
  • 用 CSS 变量集中管理。把–brand-h、–brand-c 抽成变量,深浅色全部由 L 派生,后续调整一改全改。

最小实验:打开任意一个 OKLCH 取色器,锁定色相、只拖动 L 滑块——这一下子就能体会到「明度终于听话了」。

参考链接

  • com— 交互式 OKLCH 取色与对比工具
  • fyi— OKLCH 调色板生成器
  • MDN:oklch()— 语法与浏览器兼容性
  • CSS Color Module Level 4 规范(W3C)— 权威定义与转换公式
  • Björn Ottosson 博客 — Oklab / OKLCH 原始提出者的说明
0