OKLCH以人为本的色彩空间
基于 OKLCH 生成色阶,更容易组织均匀、符合人眼明暗感受的颜色变化
色彩空间可以理解成一套记录和计算颜色的坐标。渐变在哪个色彩空间里计算,中间结果就会不同。
- RGB 用红、绿、蓝三个通道描述颜色。网页里常用的 sRGB 属于这一类,Hex 是它常见的一种写法。
- HSL 以 sRGB 为基础,用色相、饱和度和明度描述颜色。
- OKLCH 是 OKLab 的一种表示方式,它的空间可以想象成一块不规则水晶,用 L、C、H 分别表示明度、色度和色相。
相比熟悉的 RGB,OKLCH 仍比较陌生。不过 oklch() 已写入 CSS Color Level 4,并从 2023 年 5 月起获 主流浏览器支持,可以直接用于日常 CSS。
下面对比这三种色彩空间,看看 OKLCH 的优点在哪里。
OKLCH 解决了哪些痛点
跨过色相,亮度仍然更接近
比如在 Figma 里拖动 Hue,你可能见过这种变化:明明只换了色相,黄色突然显得更亮,蓝色却沉了下去。HSL 里相同的 L,不代表人眼感受到的亮度相同;OKLCH 固定 L 和 C 后再改变 H,更容易让一组颜色保持接近的视觉重量。
只改变色相,亮度还一样吗?
hsl( 100% 50%)hsl( 100% 50%)oklch(0.8 0.2 )oklch(0.8 0.2 )避开渐变中间的灰色脏带
灰色脏带(Gray Dead Zone)常见于 gamma 编码的 sRGB 逐通道插值。在 RGB 坐标中,这种插值是一条直线;换算到感知坐标后,它可能靠近低色度区域,让中段显得灰暗,非线性的传递函数还可能使中段偏暗。HSL 会沿色环改变 Hue,可能绕过灰色,也可能经过没有主动选择的颜色。OKLCH 能保留更多色度,同时把 Hue 路径交给我们决定。
同样的两个端点,中间可以完全不同
端点完全相同,只改变中间颜色的计算方式。
两套坐标,两种插值路径
sRGB 直线属于 RGB 坐标,OKLCH 弧线属于 L/C/H 坐标;两条线共用颜色端点,但不是同一坐标系里的几何轨迹。
逐通道的直线路径
在 R、G、B 坐标中沿直线插值;换算后,中段可能靠近低色度区域。
可指定方向的 Hue 路径
在 L、C、H 坐标中沿 Hue 方向变化,中段可以保留更多色度。
在 CSS 渐变的方向后加上 in oklch,就能指定 OKLCH 作为插值空间;需要控制中间经过哪些颜色时,再指定 Hue 路径。
为渐变指定插值空间和 Hue 路径
.garden-gradient { background: linear-gradient( 90deg in oklch increasing hue, oklch(70% 0.16 345), oklch(74% 0.14 165) );}这段写法多了两个部分:
in oklch:让浏览器在 OKLCH 中计算两个颜色之间的过渡。increasing hue:让 Hue 始终沿角度增大的方向移动。只想走较短圆弧时,可以使用默认的shorter hue;需要经过另一侧时,也可以选择longer hue或decreasing hue。
交互状态的色阶更可预测
交互状态要拉开明暗,也要保留同一主色。下面用 HSL 和 OKLCH 从同一个蓝色生成四种状态,看看它们是否仍属于同一个颜色家族。
同一个蓝色,生成四种交互状态
从同一个起点向亮暗两端展开,看看四种状态是否仍像同一个颜色家族。
同一个蓝色向亮暗两端展开时,HSL 的浅色容易偏紫,深色容易发灰;OKLCH 更容易保持同一种蓝色。稳定也有边界:低色度会让 Hue 失去可见意义,色域映射也可能让 Hue 偏移,最终仍需放回真实界面检查。
为什么会有这些差异
OKLCH 对前面三个问题的改善来自两部分:LCH 提供一组更直观的调色坐标,底层的 OKLab 再让数值变化更接近人眼实际看到的差异。
LCH 结构把颜色写成三个可以分别调整的坐标:L 控制感知明度,C 控制颜色离灰色有多远,H 沿色环选择颜色。跨色相配色、渐变和交互状态里的变化,也都有了对应的调节方向。
拆开 oklch() 的三个坐标
oklch()再往下一层看色彩空间。OKLCH 建立在 Oklab 上,这套空间按照视觉感知重新组织颜色,让明度的数值更接近人眼看到的明暗。把同一个 sRGB 色域画成 3D 后,它在 RGB 坐标中是立方体,换到 OKLCH 坐标中则呈现不规则边界。
用 3D 看同一色域的两种坐标
跨色相
OKLCH 把明度变成一条独立的轴sRGB 没有单独的明度坐标,调亮时往往要同时移动三个通道。OKLCH 的 L 直接描述感知明度,跨过不同色相时也更接近同一视觉重量。怎么放进真实项目
日常写样式时,不需要记住每一组完整数值。#fff、#000 这类 Hex 写法依然短而方便;主题色可以在 Token 层用 OKLCH 定义一次,组件里只读取 var(--color-action)。生成色阶、转换格式和检查色域,也可以交给下面这些工具。
用 Skill 生成并检查色阶
如果颜色已经进入项目,可以把现有主色、目标色域和需要的色阶交给 Agent,让它先生成一条可以解释、可以继续修改的 Scale。这里调用的是 OKLCH Skill:它会分配 Lightness,让色度在明暗两端自然收低,并逐级检查色域。生成之后,再放进真实界面里看看效果。
使用 oklch-skill 生成好看的色阶
已安装 oklch-skill,现在可以调用了。
已生成完整的 11 阶色阶。500 保留为主色锚点;Lightness 向两端展开,每一级都按当前 L 与 Hue 的可用色度比例生成,明暗两端会自然收低。
L 95C 0.019100L 90C 0.041200L 82C 0.079300L 73C 0.130400L 67C 0.170500L 62C 0.198600L 55C 0.175700L 48C 0.153800L 39C 0.125900L 31C 0.099950L 23C 0.074先安装,再调用 /oklch-skill。悬停 Skill 名称可预览介绍。
这个 Skill 的作者 Jakub Krehel 还做了 oklch.fyi。网站把 OKLCH 的学习和试验放在一起,可以直接创建或转换颜色、生成色板和渐变,也能查看色域边界。想理解 Skill 在背后处理了什么,或者先用界面试几个数值,可以从这个网站开始。
不想用 AI:用 Spectr 生成并预览色阶
如果这次不想用 AI,也可以直接打开可视化工具。把一张图片交给 Spectr,它会从主色中生成 Primary 与 Gray 色阶,并把结果放进按钮、文字、登录表单和数据卡等组件里实时预览。选好方向后,可以继续调整颜色,再导出成 Tailwind CSS 色板。
总结一下,OKLCH 的原理和细节可以慢慢消化。实际写 CSS 时,可以先从一个习惯开始:在项目中优先用 oklch() 替代 rgb(),渐变时写上 in oklch。这样更容易让不同交互状态保持同一主色,渐变中段也不容易发灰。

