news 2026/5/15 10:48:08

现代 CSS 颜色使用指南进阶篇

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
现代 CSS 颜色使用指南进阶篇

在上篇文章,我们学会了现代 CSS 颜色的基础用法。

本篇我们进入更高级的领域:如何像设计师一样操纵颜色

CSS 现在能做的事情,甚至比设计软件还要强大!

1. 操纵颜色

1.1. 基础回顾

先复习一下上篇文章的内容:

:root{--primary:#ff0000;}.primary-bg-50-opacity{/* h s l 不是字母,是变量! */background:hsl(fromvar(--primary)h s l / 0.5);}

注意:h s l这三个字母其实是变量,分别存储了色相(hue)、饱和度(saturation)、亮度(lightness)的值。

我们可以替换这些变量,比如给绿色(#00ff00)加点蓝:

/* 基础绿色没有蓝色成分 */.green-with-a-touch-of-blue{/* 在蓝色通道加 25 */color:rgb(from #00ff00 r gcalc(b + 25));}

这就像调色板,在基础的绿色中,添加点“蓝色颜料”。

1.2. 实用技巧

掌握了基础用法,我们就可以讲些实际开发中会用到的场景了。

  1. 创建互补色(色轮对面的颜色):
:root{--color-primary:#2563eb;/* 蓝色 *//* 色相加 180 度,跳到对面 */--color-secondary:hsl(fromvar(--color-primary)calc(h + 180)s l);}
  1. 创建三色组合:
:root{--color-primary:#2563eb;/* 色轮上均匀分布 120 度 */--color-secondary:hsl(fromvar(--color-primary)calc(h + 120)s l);--color-tertiary:hsl(fromvar(--color-primary)calc(h - 120)s l);}

就像时钟:12 点是主色,4 点和 8 点是配色,完美对称!

使用效果如下:

  1. 相对调整
:root{--color-primary-base:#2563eb;/* 比基础色亮 25% */--color-primary-lighter:hsl(fromvar(--color-primary-base)h scalc(l + 25));/* 比基础色暗 25% */--color-primary-darker:hsl(fromvar(--color-primary-base)h scalc(l - 25));}

使用这种方法,不管基础色是多亮,都会相对地变亮或变暗。

这就像调空调,“比现在低 5 度”比“设定到 20 度”更灵活。

使用效果如下:

2. 暗黑模式的层次感

现在我们能相对调整颜色了,可是究竟有什么用呢?

让我给你举个具体的使用场景。

在浅色主题中,我们可以根据阴影来区分层次:

但在深色背景下,阴影的效果并不明显。

因此在深色主题中,我们希望每个层次的颜色略微变浅。

借助上篇讲过的light-dark()和相对颜色调整,我们便可以实现:

:root{--surface-base-light:hsl(240 67% 97%);--surface-base-dark:hsl(252 21% 9%);}/* 第一层:基础层 */.surface-1{background:light-dark(var(--surface-base-light),var(--surface-base-dark));}/* 第二层:稍微亮一点 */.surface-2{background:light-dark(var(--surface-base-light),hsl(fromvar(--surface-base-dark)h scalc(l + 4)));}/* 第三层:再亮一点 */.surface-3{background:light-dark(var(--surface-base-light),hsl(fromvar(--surface-base-dark)h scalc(l + 8)));}

想象一下深海:越接近水面,光线越充足。暗色模式的层次就是这个原理。

使用效果如下:

3. 完整配色方案

设计师创建配色方案时,不只是简单地调整亮度,还会同时微调色相和饱和度,比如

  • 变亮时:饱和度增加,色相向冷色调偏移
  • 变暗时:饱和度降低

这便可以通过 CSS 来实现:

:root{--primary-base:hsl(221 83% 50%);/* 400: 亮度60%,色相-3度,饱和度+5% */--primary-400:hsl(fromvar(--primary-base)calc(h - 3)calc(s + 5)60%);/* 300: 亮度70%,色相-6度,饱和度+10% */--primary-300:hsl(fromvar(--primary-base)calc(h - 6)calc(s + 10)70%);/* 以此类推... */}

为什么要这么麻烦呢?

因为只调亮度会让浅色看起来“失去活力”。

就像拍照:自动模式能拍,但手动调整曝光、对比度、色温会更漂亮。

为了让你更直观地看到变化:

第一排是都调整的版本,第二排是未调整色相和饱和度的版本。

最明显的区别在于 100、200 和 300 这几个色块,当仅调整亮度值时,颜色看起来失去了一些鲜艳度。

4. OKLCH 更科学的配色方式

4.1. 问题:HSL

HSL 虽然很棒,但在使用时,你会发现一些问题,让我们看个例子:

.green-bg{/* 饱和度 100%,亮度 50% */background:hsl(100 100% 50%);color:white;}.blue-bg{/* 同样饱和度 100%,亮度 50% */background:hsl(220 100% 50%);color:white;}

你会发现,色和蓝色的饱和度、亮度虽然完全一样,但视觉效果完全不同:

明显蓝色背景上的文字清晰易读,对比度超过 5,而绿色背景上的文字却很难看清,对比度仅略高于 1。

之所以会这样,是因为 HSL 的“亮度”不符合人眼感知。

人眼对绿色比蓝色更敏感,所以同样的“50%亮度”,绿色看起来更亮。

4.2. 解决:OKLCH

而这就是 oklch() 的优势。

OKLCH 是基于感知亮度设计的:

.consistent-green{background:oklch(0.54 0.23 261);}.consistent-blue{background:oklch(0.54 0.23 146);}

使用效果如下:

现在不管什么颜色,亮度值相同,人眼看起来的亮度就相同!

4.3. 讲解:OKLCH 的三个参数

在 LCH 颜色模型中:

第一个值是亮度(Lightness),取值范围为 0 到 1。它的计算方式与 HSL 略有不同,因为它基于感知亮度,但概念相同,即 0 是黑色,1 是白色。

第二个值是色度(Chroma),类似于饱和度,0 是灰色,越大越鲜艳,但最大值不固定,取决于亮度和色相(这是 OKLCH 最麻烦的地方)

第三个值是色相(Hue),和 HSL 一样是色轮,0 到 360 度,区别是 0 度是洋红色(HSL 里 0 度是红色)

OKLCH 的尴尬之处就在于色度(Chroma)的最大值会变:

/* 某些色相+亮度组合,0.4 已经是极限 */.max-chroma-1{background:oklch(0.6 0.4 120);}/* 但另一些组合,0.4 可能太高或太低 */.max-chroma-2{background:oklch(0.8 0.4 200);/* 可能超出范围 */}

就像不同口味的饮料,有的最浓是“3 勺糖”,有的最浓是“5 勺糖”,没有统一标准。

4.4. 实用技巧:结合相对颜色

虽然直接写 OKLCH 值很麻烦,但我们可以用 HSL 定义基础色,然后用 OKLCH 保持一致性:

.toast{--base-color:hsl(225,87%,56%);/* 用熟悉的 HSL 定义 */}[data-toast="info"]{/* 只改变色相,保持亮度和色度 */--toast-color:oklch(fromvar(--base-color)l c 275);}[data-toast="warning"]{--toast-color:oklch(fromvar(--base-color)l c 80);}[data-toast="error"]{--toast-color:oklch(fromvar(--base-color)l c 35);}

使用效果如下:

这样做的好处在于:不同颜色的提示框,边框对比度、整体饱和度感觉都很一致。

5. 混合颜色

有的时候,我们可能需要混合两种颜色:

.purple{/* 红色和蓝色各占 50% */color:color-mix(in srgb,red,blue);}

就像调颜料:红色颜料加蓝色颜料,得到紫色。

目前必须定义一个颜色空间,所以必须写in srgbin oklab等,未来会默认用oklab

不同颜色空间混出来的结果不一样:

一般推荐:

  1. 先试oklab
  2. 再试oklch
  3. 不满意就换其他的

5.1. 控制混合比例

默认情况下,使用该功能时color-mix(),每种颜色将使用 50% 的强度。

当然,我们也可以控制特定颜色的具体强度。

/* 90% 红色 + 10% 蓝色 */.red-with-a-touch-of-blue{background:color-mix(in oklab,red 90%,blue);}/* 或者反过来写 */.or-like-this{background:color-mix(in oklab,red,blue 10%);}

5.2. 创建半透明色

有两种方法可以获得透明的值:

方法一:让总量小于 100%

/* 60% + 20% = 80%,所以透明度是 80% */.semi-opaque{background:color-mix(in oklab,red 60%,blue 20%);}

方法二:混入 transparent

/* 30% 的不透明红色 */.thirty-percent-opacity-red{background:color-mix(in oklch,red 30%,transparent);}

不过如果只是想降低透明度,还是用相对颜色更直接:

.better-way{background:rgb(from red r g b / 0.3);}

5.3. 小技巧:分段渐变

/* 不用手动算中间的每个颜色,color-mix 帮你搞定 */.banded-gradient{background:linear-gradient(to right,red,color-mix(in oklch,red 75%,blue),color-mix(in oklch,red 50%,blue),color-mix(in oklch,red 25%,blue),blue);}

使用效果如下:

6. 未来更简单

重复写这些代码很烦?

CSS 自定义函数快来了:

/* 定义函数 */@function--lower-opacity(--color,--opacity){result:oklch(fromvar(--color)l c h /var(--opacity));}/* 使用函数 */.lower-opacity-primary{background:--lower-opacity(var(--primary),0.5);}

或者定义整套色阶函数:

@function--shade-100(--color)returns <color>{result:hsl(fromvar(--color)calc(h - 12)calc(s + 15)95%);}@function--shade-200(--color)returns <color>{result:hsl(fromvar(--color)calc(h - 10)calc(s + 12)85%);}/* 以此类推... */.call-to-action{background:--shade-200(var(--accent));}.hero{background:--shade-800(var(--primary));color:--shade-100(var(--primary));}

一次定义,到处使用,完美!

7. 总结

最后总结下本篇文章的重点:

  1. 用 calc() 操纵颜色- 数学生成配色方案
  2. OKLCH- 基于人眼感知的颜色系统,不同色相亮度一致
  3. color-mix()- 像调颜料一样混合颜色

在实际使用时:

  • 简单需求:相对颜色 + HSL
  • 需要视觉一致性:OKLCH
  • 需要混合颜色:color-mix()
  • 暗黑模式层次:light-dark() + 相对颜色

本篇整理自《A pragmatic guide to modern CSS colours - part two》,希望能帮助到你。

我是冴羽,10 年笔耕不辍,专注前端领域,更新了 10+ 系列、300+ 篇原创技术文章,翻译过 Svelte、Solid.js、TypeScript 文档,著有小册《Next.js 开发指南》、《Svelte 开发指南》、《Astro 实战指南》。

欢迎围观我的“网页版朋友圈”,关注我的公众号:冴羽(或搜索 yayujs),每天分享前端知识、AI 干货。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/15 7:14:35

一步API+Gemini 3.0 Pro进阶实战:多模态开发、性能调优与项目落地

一、多模态开发实战&#xff1a;图文/音文交互全解析 Gemini 3.0 Pro原生支持文本、图片、音频多模态输入输出&#xff0c;一步API完美兼容其能力&#xff0c;无需额外适配跨境传输&#xff0c;国内环境可直接调用。以下聚焦两大高频场景&#xff0c;拆解核心实现逻辑与关键代码…

作者头像 李华
网站建设 2026/5/11 21:32:45

传统问卷设计 VS 虎贲等考 AI:3 天工作量压缩到 30 分钟的科研效率革命

还在为一份学术问卷熬秃脑袋&#xff1f;翻遍文献找量表却不知如何本土化修订&#xff0c;设计好的问卷因问题歧义导致数据失真&#xff0c;回收几百份问卷后才发现信效度不达标…… 在实证研究里&#xff0c;问卷设计堪称 “第一道生死关”。据调研显示&#xff0c;超 65% 的社…

作者头像 李华
网站建设 2026/5/9 3:17:03

AI 写论文哪个软件最好?实测虎贲等考 AI:毕业论文的学术通关加速器

毕业季的论文攻坚战里&#xff0c;“AI 写论文哪个软件最好” 的灵魂拷问&#xff0c;总能在高校互助群里刷屏。有人踩坑通用 AI 的 “文献幻觉”&#xff0c;有人栽在单一工具的 “功能割裂”&#xff0c;还有人被查重和 AIGC 检测的双重门槛难住。作为深耕论文写作科普的测评…

作者头像 李华
网站建设 2026/5/10 23:52:26

建筑施工扬尘监测仪厂家:金叶仪器技术解析与现场应用实践指南

在建筑施工过程中&#xff0c;扬尘污染是常见的环境问题之一&#xff0c;它不仅影响周边空气质量&#xff0c;还可能对居民健康和生态平衡带来潜在影响。随着环保意识的提升和相关法规的逐步完善&#xff0c;施工扬尘的监测与管理成为项目现场的重要环节。金叶仪器&#xff08;…

作者头像 李华
网站建设 2026/5/10 8:57:33

手把手搭建本地RAG知识库!实现文档秒检索。

文章详细介绍如何使用开源模型nomic-embed-text搭建本地RAG知识库&#xff0c;实现高效文档检索。内容包括模型基本信息、特性对比和应用场景&#xff0c;以及完整搭建步骤&#xff1a;下载模型、创建工作区、上传文档、向量化存储和检索测试。同时提供了两种使用方式&#xff…

作者头像 李华
网站建设 2026/5/11 2:37:22

Python优势:为何适合新手入门与数据分析

Python作为一门脚本语言&#xff0c;其优势不仅体现在语法简洁上&#xff0c;更在于它构建了一个庞大而实用的生态系统。从我多年的使用经验来看&#xff0c;Python的核心价值在于它极大地降低了技术应用的准入门槛&#xff0c;让开发者能将精力聚焦于问题本身&#xff0c;而非…

作者头像 李华