【CSS in Depth 2 精译_069】11.3 利用 OKLCH 颜色值来处理 CSS 中的颜色问题(上)

当前内容所在位置(可进入专栏查看其他译好的章节内容)

  • 第四部分 视觉增强技术 ✔️
  • 【第 11 章 颜色与对比】 ✔️
    • 11.1 通过对比进行交流
      • 11.1.1 模式的建立
      • 11.1.2 还原设计稿
    • 11.2 颜色的定义
      • 11.2.1 色域与色彩空间
      • 11.2.2 CSS 颜色表示法
        • 11.2.2.1 RGB 与 十六进制颜色
        • 11.2.2.2 HSL 颜色表示法
        • 11.2.2.3 HWB 颜色表示法
        • 11.2.2.4 新一代色彩空间
        • 11.2.2.5 LAB 和 OKLAB 颜色表示法
        • 11.2.2.6 LCH 和 OKLCH 颜色表示法
      • 11.3 利用 OKLCH 处理颜色(上篇) ✔️
        • 11.3.1 把样式表切换到 OKLCH 色彩空间(上篇) ✔️
        • 11.3.2 颜色变量的命名(上篇) ✔️
        • 11.3.3 为调色板选取新的颜色(上篇) ✔️
        • 11.3.4 从页面其他颜色衍生出新颜色(下篇)

《CSS in Depth》新版封面

《CSS in Depth》新版封面

译者按
本篇又来到了 CSS 颜色专题的另一个全新小节—— OKLCH 颜色表示法的具体应用。由于篇幅较长,拟分为上下两篇进行介绍,本篇为 11.3 节的上篇,主要介绍了 OKLCH 颜色值在浏览器中的查看方法以及在 CSS 颜色管理中的具体用法。就像作者说的,掌握知识点的最佳途径就是付诸实践,勤加练习。一起学起来吧!

11.3 利用 OKLCH 处理颜色 Using OKLCH to work with color

接下来,我将教您如何将十六进制颜色转换为其他的写法。很多在线资源都提供了颜色提取工具,并支持不同颜色表示法之间的相互转换。但进行颜色转换最简单的去处莫过于本地浏览器的开发者工具(DevTools)了,毕竟该工具唾手可得。下面演示如何在 Chrome 浏览器中进行颜色转换。

您可以按照这套流程把颜色值转换成您想要的写法。如果担心浏览器不兼容,建议选用 HSL 表示法。而我将用 OKLCH 来进行演示,因为浏览器对它的支持正在快速增长,并且也对它未来的推广普及充满信心。无论采用哪种方式,基本流程都是一样的。

注意

截止到 2024 年年中,Firefox 浏览器的开发者工具 DevTools 尚不支持将 CSS 颜色转为某些新推出的颜色表示方法。本节截图显示的是 Chrome 浏览器中的 DevTools 工具。

页面加载后,打开浏览器的 DevTools 开发者工具(按 F12 键)。在 Elements 元素面板中单击并选中 <html> 标签,就会在 Styles 样式面板中看到对应的样式,其中包括我们设置的自定义属性(如图 11.13 所示)。

图 11.13 页面生效的颜色在 DevTools 的样式面板下的截图。按住 Shift 键单击颜色旁边的小方块可以切换不同的颜色表示方法

【图 11.13 页面生效的颜色在 DevTools 的样式面板下的截图。按住 Shift 键单击颜色旁边的小方块可以切换不同的颜色表示方法】

每种颜色旁边都有一个正方形的小指示器(indicator)来显示该颜色的效果。如果按住 Shift 键,然后单击这个小方块,就可以将这个十六进制颜色值转换成另一种写法。在 FirefoxSafari 浏览器中,每次单击都会在不同的颜色表示法之间循环;而在 Chrome 浏览器下,这样会弹出一个下拉菜单,以供用户选择。

如果还想深入研究,单击小方块就可以打开一个完整的颜色提取器对话框(如图 11.14 所示)。利用该对话框,您可以对当前颜色进行微调,或者从调色板中选取想要的颜色,或者是在不同的颜色值语法间切换。同时它还提供了一个滴管形状的颜色提取器,以便直接从页面选取目标颜色。尽管 FirefoxSafari 浏览器也提供了类似的颜色提取工具,但是功能没有 Chrome 这么丰富。

图 11.14 利用颜色提取器对话框来对颜色进行微调

【图 11.14 利用颜色提取器对话框来对颜色进行微调】

当颜色提取工具处于某个广色域色彩空间时,调色板中会出现一条细长的白线。它表示 sRGB 色域标准的边界。分界线左侧的颜色属于 sRGB 色域,可在支持 sRGB 标准的显示器上精确显示;而分界线右侧更为鲜艳的色彩则超出了 sRGB 色域范围,但属于 Display P3 色域的一部分;如果使用这些区域的颜色,sRGB 显示器将按最接近的颜色渲染,但并不那么精确。

11.3.1 把样式表切换到 OKLCH 色彩空间 Switching the stylesheet to OKLCH

通常情况下颜色值按十六进制格式书写即可。但转换成 HSL 值或 OKLCH 值可以更方便地进行颜色微调,也更容易找到可以添加到网站的新颜色。下面尝试将网站颜色都转换成 OKLCH 格式,然后对页面颜色做一些深度观察。

注意

尽管颜色表示法中的很多参数值都可以写成不带单位的普通数字,但我个人更倾向于在适当的场合写上单位。比如写作 oklch(45% 0.09 165.4deg) 而不是 oklch(0.45 0.09 165.4),因为我认为这样写能够一目了然地识别出哪个值对应哪个参数,特别是 deg 单位,可以立马知道它代表色调。

DevTools 工具中的 OKLCH 颜色值分别复制到样式表中,替换掉之前的十六进制格式。为确保简洁,我还对部分几乎看不出区别的颜色值做了圆整处理,并加上了对应的单位,使其更加清晰明了。

代码清单 11.6 将十六进制颜色转换成 OKLCH 值

@layer theme {
  :root {
    /* 绿色都使用相同的色调 */
    --brand-green: oklch(45% 0.09 165.4deg);
    --dark-green: oklch(59% 0.12 164.1deg);
    --medium-green: oklch(74% 0.15 166.4deg);

    /* 部分灰色值都不是纯灰色 */
    --text-color: oklch(26% 0.01 0deg);
    --gray: oklch(64% 0.02 248deg);
    --light-gray: oklch(96% 0.003 248deg);
    
    --extra-light-gray: oklch(98% 0 0deg);
    --white: oklch(100% 0 0deg);
  }
}

把颜色都改成 OKLCH 写法后,有些事情就变得显而易见了。首先,您会发现三种绿色都拥有相同的色调值。如果不在浏览器中查看,估计很难一下子识别出 165 表示一种青绿色(teal green),但却很容易发现这三种颜色存在某些相似之处(symmetry)。这些特征在十六进制颜色值下是很难察觉的,但是转成 OKLCH 后就比较明显了。了解这些之后,在调色板中再加一种绿色就容易多了。如果需要同种颜色的浅色调版本,就可以尝试写作 oklch(85% 0.12 165deg),然后在浏览器的 DevTools 开发者工具中对饱和度或色度(chroma)再做微调,直到最终效果满意为止。

提示

如果要配置好几种相似的颜色,也可以将单个值(如色调的角度值)赋给一个自定义属性,然后在定义颜色时调用该属性。例如 oklch(45% 0.09 var(--brand-hue))

您可能也注意到了,上述颜色代码中的灰色并不是纯灰色:有几个颜色略带了些色度。单看这些颜色本身,可能还看不出这些门道,但就是这样的小细节能让我们的页面看上去更加丰富多彩。真实世界中鲜有完全不掺杂彩色的纯灰色(colorless grays),而且我们的眼睛也乐于看到一些彩色,哪怕是极其细微的彩色。

再次强调,在实际项目开发中,我们没有必要把所有颜色值都转换成 OKLCH 格式;什么时候有这样的需求了再考虑转换也不迟。通常情况下,这样的转换可以更方便地找到相关的颜色。

本书后续章节的示例都会继续采用 OKLCH 格式的颜色值来进行演示。对于实际项目,请务必在 Can I Use 官网(详见 https://caniuse.com/mdn-css_types_color_oklch)查看最新的浏览器兼容情况,并为该写法提供在低版本浏览器中的备用值,直到您对当前的兼容情况感到满意为止。

11.3.2 颜色变量的命名 Naming color variables

设计师一般会在调色板中设计多个不同的灰色。不过按照我的经验,即使准备得再充分,也免不了需要补充其他灰色值。无论是比超浅灰(extra-light gray)更浅的版本,抑或是介于灰色和浅灰色之间的某种颜色,类似的需求总是存在的。有时甚至是品牌主色也面临这样的情况。打个比方,您可能到头来会发现,除了页面上已有的三种绿色之外,还需要引入另一种绿色。这样一来,颜色变量的命名管理就成了个问题。

基于这样的原因,可以考虑使用带数值的名称来命名颜色值,例如 --gray-50 或者 --gray-80,这里的数字大致对应亮度值。这样就能在必要的时候,在现有的颜色值之间再插入另一个新的颜色值。现如今,网站通常都会有一个长长的自定义属性列表来定义不同的颜色,例如从 --blue-10 定义到 --blue-90,或者从 --gray-10 指定到 --gray-90

遇到大型网站或者更复杂的应用场景,通常会将这些 “原始”(“raw”)颜色变量依次赋给某个二级变量,例如一组带编号的前景色与背景色,如代码清单 11.7 所示(无需将其添加到本章构建的示例页中)。

代码清单 11.7 从基于用途的自定义变量中抽象出原始的颜色值

:root {
  --gray-10: oklch(10% 0.01 165deg);
  --gray-20: oklch(23% 0.01 165deg);
  --gray-30: oklch(35% 0.01 165deg);
  --gray-40: oklch(42% 0.01 165deg);
  --gray-50: oklch(53% 0.01 165deg);
  --gray-60: oklch(65% 0.01 165deg);
  --gray-70: oklch(78% 0.01 165deg);
  --gray-80: oklch(90% 0 165deg);
  --gray-90: oklch(98% 0 165deg);

  --background-4: var(--gray-90);
  --background-3: var(--gray-80);
  --background-2: var(--gray-70);
  --background-1: var(--gray-60);
  --background-neutral: var(--gray-50);
  --foreground-1: var(--gray-40);
  --foreground-2: var(--gray-30);
  --foreground-3: var(--gray-20);
  --foreground-4: var(--gray-10);
}

您还可以添加一些变量,专门给边框、阴影效果以及其他可复用的设计元素设计颜色。然后,在整个样式表中使用这些二级变量(secondary variables),而不是直接使用原始的颜色值变量。利用这样的间接设置,您就可以实现特定颜色值的修改与其具体用途间的分离。比如要更换通用的边框颜色,就可以在二级变量的帮助下顺利完成修改,不会对同样作为下拉菜单背景的那个灰色带来不良影响。

该方案也特别适用于浅色模式和深色模式的设置,可以在保持原始颜色值不变的情况下,实现背景色与前景色的样式反转(或许可以在容器样式查询中进行尝试,具体方法详见第 10 章)。

管理颜色变量的具体方法数不胜数,而且并没有公认的最佳方案。我也一直很喜欢浏览一些我所尊敬的开发者和设计师创建的网站,并学习上面的 CSS。每个人都有自己独到的解决方案。建议您多去尝试一些适合自己的方案,并根据自己的风格进行调整。

11.3.3 为调色板选取新的颜色 Selecting new colors for the palette

试想有这样一个场景,您需要某种颜色,而设计师刚好没有提供,比如红色的报错信息或者蓝色的信息框。有经验的设计师一般会对这种情况提供通用的解决方案,但您可能仍需要考虑将新颜色添加到调色板中。

我们的样式表已经为激活状态下的链接文本颜色预留了位置。激活状态下的链接通常为红色,这也是用户代理样式表提供的默认样式;但这种红色过于鲜艳,看起来也略显卡通(cartoony),与当前的页面风格不一致;需要换成一种不那么鲜艳的、能与页面中的绿色相搭配的颜色。

(上篇完)



关于《CSS in Depth》(中译本书名《深入解析 CSS》)

第 1 版第 2 版
读者评分原版:4.7(亚马逊);中文版:9.3(豆瓣)原版:5.0(亚马逊);中文版:暂无,待出版
出版时间原版:2018 年 3 月;中文版:2020 年 4 月原版:2024 年 7 月;中文版:暂无,待出版
原价原版:$44.99;中文版:¥139.00原版:$59.99;中文版:暂无,待出版
现价原版:$36.49;中文版:¥52.54 起步原版:$52.09;中文版:暂无,待出版
原版国内预订起步价 ¥461.00起步价 ¥750.00

本专栏为该书第 2 版高分译文专栏,全网首发,精译精校,持续更新,计划今年内完成全书翻译,敬请期待!!!

目前已完结的章节(可进入本专栏查看详情,连载期间完全免费):

  • 第一章 层叠、优先级与继承(已完结)
    • 1.1 层叠
    • 1.2 继承
    • 1.3 特殊值
    • 1.4 简写属性
    • 1.5 CSS 渐进式增强技术
    • 1.6 本章小结
  • 第二章 相对单位(已完结)
    • 2.1 相对单位的威力
    • 2.2 em 与 rem
    • 2.3 告别像素思维
    • 2.4 视口的相对单位
    • 2.5 无单位的数值与行高
    • 2.6 自定义属性
    • 2.7 本章小结
  • 第三章 文档流与盒模型(已完结)
    • 3.1 常规文档流
    • 3.2 盒模型
    • 3.3 元素的高度
    • 3.4 负的外边距
    • 3.5 外边距折叠
    • 3.6 容器内的元素间距问题
    • 3.7 本章小结
  • 第四章 Flexbox 布局(已完结)
    • 4.1 Flexbox 布局原理
    • 4.2 弹性子元素的大小
    • 4.3 弹性布局的方向
    • 4.4 对齐、间距等细节处
    • 4.5 本章小结
  • 第五章 网格布局(已完结)
    • 5.1 构建基础网格
    • 5.2 网格结构剖析 (上)
      • 5.2.1 网格线的编号(下)
      • 5.2.2 网格与 Flexbox 配合(下)
    • 5.3 两种替代语法
      • 5.3.1 命名网格线
      • 5.3.2 命名网格区域
    • 5.4 显式网格与隐式网格(上)
      • 5.4.1 添加变化 (中)
      • 5.4.2 让网格元素填满网格轨道(下)
    • 5.5 子网格(全新增补内容)
    • 5.6 对齐相关的属性
    • 5.7 本章小结
  • 第六章 定位与堆叠上下文(已完结)
    • 6.1 固定定位
      • 6.1.1 创建一个固定定位的模态对话框
      • 6.1.2 在模态对话框打开时防止屏幕滚动
      • 6.1.3 控制定位元素的大小
    • 6.2 绝对定位
      • 6.2.1 关闭按钮的绝对定位
      • 6.2.2 伪元素的定位问题
    • 6.3 相对定位
      • 6.3.1 创建下拉菜单(上)
      • 6.3.2 创建 CSS 三角形(下)
    • 6.4 堆叠上下文与 z-index
      • 6.4.1 理解渲染过程与堆叠顺序(上)
      • 6.4.2 用 z-index 控制堆叠顺序(上)
      • 6.4.3 深入理解堆叠上下文(下)
    • 6.5 粘性定位
    • 6.6 本章小结
  • 第七章 响应式设计(已完结)
    • 7.1 移动端优先设计原则(上篇)
      • 7.1.1 创建移动端菜单(下篇)
      • 7.1.2 给视口添加 meta 标签(下篇)
    • 7.2 媒体查询(上篇)
      • 7.2.1 深入理解媒体查询的类型(上篇)
      • 7.2.2 页面断点的添加(中篇)
      • 7.2.3 响应式列的添加(下篇)
    • 7.3 流式布局
    • 7.4 响应式图片
    • 7.5 本章小结
  • 第八章 层叠图层及其嵌套
    • 8.1 用 layer 图层来操控层叠规则(上篇)
      • 8.1.1 图层的定义(上篇)
      • 8.1.2 图层的顺序与优先级(下篇)
      • 8.1.3 revert-layer 关键字(下篇)
    • 8.2 层叠图层的推荐组织方案
    • 8.3 伪类 :is() 和 :where() 的用法
    • 8.4 CSS 嵌套的使用
      • 8.4.1 嵌套选择器的使用
      • 8.4.2 深入理解嵌套选择器
      • 8.4.3 媒体查询及其他 @规则 的嵌套
    • 8.5 本章小结
  • 第九章 CSS 的模块化与作用域
    • 9.1 模块的定义
      • 9.1.1 模块和全局样式
      • 9.1.2 一个简单的 CSS 模块
      • 9.1.3 模块的变体
      • 9.1.4 多元素模块
    • 9.2 将模块组合为更大的结构
      • 9.2.1 模块中多个职责的拆分
      • 9.2.2 模块的命名
    • 9.3 CSS 的作用域
      • 9.3.1 CSS 作用域的就近原则
      • 9.3.2 划定作用域的边界
      • 9.3.3 CSS 中的隐式作用域
      • 9.3.4 关于 CSS 作用域与层叠图层
    • 9.4 CSS 模式库
    • 9.5 本章小结
  • 第十章 CSS 容器查询
    • 10.1 容器查询的一个简单示例
      • 10.1.1 容器尺寸查询的用法
    • 10.2 深入理解容器
      • 10.2.1 容器的类型
      • 10.2.2 容器的名称
      • 10.2.3 容器与模块化 CSS
    • 10.3 与容器相关的单位
    • 10.4 容器样式查询的用法
      • 10.4.1 将模块与所在容器解耦
      • 10.4.2 减少重复代码
    • 10.5 本章小结
  • 附录
    • 附录A:CSS 选择器参考
    • 附录B:CSS 预处理器简介
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

安冬的码畜日常

您的鼓励是我持续优质内容的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值