在 23 年的 CSS 新特性中,有一个非常重要的功能更新 -- 相对颜色

简单而言,相对颜色的功能,让我们在 CSS 中,对颜色有了更为强大的掌控能力。

其核心功能就是,让我们能够基于一个现有颜色 A,通过一定的转换规则,快速生成我们想要的颜色 B

其功能能够涵盖:

完整的教程,你可以看这里 -- Chrome for Developers- CSS 相对颜色语法

当然,今天我们不会一个一个去过这些功能,更多的时候,我们只需要知道我们能够实现这些功能。

本文,我们将从实际实用角度出发,基于实际的案例,看看 CSS 相对颜色,能够如何解决我们的一些实际问题。

快速语法入门

首先,我们通过一张图,一个案例,快速入门 CSS 相对颜色语法:

相对颜色语法的目标是允许从另一种颜色派生颜色。

上图显示了将原始颜色 green 转换为新颜色的颜色空间后,该颜色会转换为以 r、g、b 和 alpha 变量表示的各个数字,这些数字随后会直接用作新的 rgb() 颜色的值。

举个例子:

<p> CSS Relative Color </p>
p {
color: rgb(255, 0, 0);
}

实现一个 color 为红色(rgb 值为 rgb(255, 0, 0))的字体:

基于上面的相对颜色语法,我如何通过一个红色生成绿色文字呢?示意如下:

p {
--color: rgb(255, 0, 0);
color: rgb(from var(--color) calc(r - 255) calc(g + 255) b); /* result = rgb(0, 255, 0) */
}

效果如下,我们就得到绿色字体:

解释一下:

  1. 原本的红色颜色,我们把它设置为 CSS 变量 --color: rgb(255, 0, 0)
  2. 想通过红色得到绿色,对于红色的 rgb 值 rgb(255, 0, 0) 而言,需要转换成 rgb(0, 255, 0)
  3. 使用 CSS 相对颜色语法,就是 rgb(from var(--color) calc(r - 255) calc(g + 255) b)

通过这个 DEMO,我们把几个核心基础语法点学习一下:

  1. from 关键字

from 关键字,它是相对颜色的核心。它表示会将 from 关键字后的颜色定义转换为相对颜色!在 from 关键字后面,CSS 会期待一种颜色,即能够启发生成另一种颜色

  1. from 关键字 后的颜色表示,支持不同颜色表示或者是 CSS 变量

第二个关键点,from 后面通常会接一个颜色值,这个颜色值可以是任意颜色表示法,或者是一个 CSS 变量,下面的写法都是合法的:

p {
color: rgba(from #ff0000) r g b);
color: rgb(from rgb(255, 0, 0) r g b);
color: rgb(from hsl(0deg, 100%, 50%) r g b);
color: rgb(from var(--hotpink) r g b);
}
  1. 对转换后的变量使用 calc() 或其他 CSS 函数

另外一个非常重要的基础概念就是,我们可以对 (from color r g b) 后的转换变量 r g b 使用 calc() 或其他 CSS 函数。

就是我们上面的例子:

p {
--color: rgb(255, 0, 0);
color: rgb(from var(--color) calc(r - 255) calc(g + 255) b); /* result = rgb(0, 255, 0) */
}
  1. 相对颜色语法支持,各种颜色表示函数:

相对颜色的基础的使用规则就是这样,它不仅支持 rgb 颜色表示法,它支持所有的颜色表示法:

使用 CSS 相对颜色,实现统一按钮点击背景切换

通常页面上的按钮,都会有 hover/active 的颜色变化,以增强与用户的交互。

像是这样:

最常见的写法,就是我们需要在 Normal 状态、Hover 状态、Active 状态下写 3 种颜色:

p {
color: #ffcc00;
transition: .3s all;
}
/* Hover 伪类下为 B 颜色 */
p:hover {
color: #ffd21f;
}
/** Active 伪类下为 C 颜色 **/
p:active {
color: #ab8a05;
}

在之前,我们介绍过一种利用滤镜 filter: contrast() 或者 filter: brightness() 的统一解决方案,无需写多个颜色值,可以根据 Normal 状态下的色值,通过滤镜统一实现更亮、或者更暗的伪类颜色。

在今天,我们也可以利用 CSS 相对颜色来做这个事情:

div {
--bg: #fc0;
background: var(--bg);
transition: .3s all;
} div:hover {
background: hsl(from var(--bg) h s calc(l * 1.2));
}
div:active {
background: hsl(from var(--bg) h s calc(l * 0.8));
}

我们通过 hsl 色相、饱和度、亮度颜色表示法表示颜色。实现:

  1. :hover 状态下,根据背景色,将背景亮度 l 调整为原背景色的 1.2 倍
  2. :avtive 状态下,根据背景色,将背景亮度 l 调整为原背景色的 0.8 倍

在实际业务中,这是一个非常有用的用法。

完整的 DEMO,你可以戳这里:CodePen Demo -- https://codepen.io/Chokcoco/pen/KKEdOeb

使用 CSS 相对颜色,实现文字颜色自适应背景

相对颜色,还有一个非常有意思的场景 -- 让文字颜色能够自适应背景颜色进行展示。

有这么一种场景,有的时候,无法确定文案的背景颜色的最终表现值(因为背景颜色的值可能是后台配置,通过接口传给前端),但是,我们又需要能够让文字在任何背景颜色下都正常展现(譬如当底色为黑色时文字应该是白色,当背景为白色时,文字应该为黑色)。

像是这样:

在不确定背景颜色的情况下,无论什么情况,文字颜色都能够适配背景的颜色。

在之前,纯 CSS 没有特别好的方案,可以利用 mix-blend-mode: difference 进行一定程度的适配:

div {
// 不确定的背景色
}
p {
color: #fff;
mix-blend-mode: difference;
}

实操过这个方案的同学都会知道,在一定情况下,前景文字颜色还是会有一点瑕疵。并且,混合模式这个方案最大的问题是会影响清晰度

有了 CSS 相对颜色后,我们有了更多的纯 CSS 方案。

利用 CSS 相对颜色,反转颜色

我们可以利用相对颜色的能力,基于背景色颜色进行反转,赋值给 color。

一种方法是将颜色转换为 RGB,然后从 1 中减去每个通道的值。

代码非常简单:

p {
/** 任意背景色 **/
--bg: #ffcc00;
background: var(--bg); color: rgb(from var(--bg) calc(1 - r) calc(1 - g) calc(1 - b)); /** 基于背景反转颜色 **/
}

用 1 去减,而不是用 255 去,是因为此刻,会将 rgb() 表示法中的 0~255 映射到 0~1

效果如下:

配个动图,我们利用背景色的反色当 Color 颜色,适配所有背景情况:

完整的 DEMO 和代码,你可以戳这里:CodePen Demo -- CSS Relatvie Color Adapt BG

当然,这个方案还有两个问题:

  1. 如果颜色恰好是在 #808080 灰色附近,它的反色,其实还是它自己!会导致在灰色背景下,前景文字不可见;
  2. 绝大部分情况虽然可以正常展示,但是并不是非常美观好看

为了解决这两个问题,CSS 颜色规范在 CSS Color Module Level 6 又推出了一个新的规范 -- color-contrast()

利用 color-contrast(),选择高对比度颜色

color-contrast() 函数标记接收一个 color 值,并将其与其他的 color 值比较,从列表中选择最高对比度的颜色。

利用这个 CSS 颜色函数,可以完美的解决上述的问题。

我们只需要提供 #fff 白色和 #000 黑色两种可选颜色,将这两种颜色和提供的背景色进行比较,系统会自动选取对比度更高的颜色。

改造一下,上面的代码,它就变成了:

p {
/** 任意背景色 **/
--bg: #ffcc00;
background: var(--bg); color: color-contrast(var(--bg) vs #fff, #000); /** 基于背景色,自动选择对比度更高的颜色 **/
}

这样,上面的 DEMO 最终效果就变成了:

完整的 DEMO 和代码,你可以戳这里:CodePen Demo -- CSS Relatvie Color Adapt BG

此方案的优势在于:

  1. 可以限定前景 color 颜色为固定的几个色值,以保证 UI 层面的统一及美观
  2. 满足任何情况下的背景色

当然,唯一限制这个方案的最大问题在于,当前,color-contrast 还只是一个实验室功能,未大规模被兼容。

总结一下

到今天,我们可以利用 CSS 提供的各类颜色函数,对颜色有了更为强大的掌控力。

很多交互效果,不借助 JavaScript 的运算,也能计算出我们想要的最终颜色值。本文简单的借助:

  1. 使用 CSS 相对颜色,实现统一按钮点击背景切换
  2. 使用 CSS 相对颜色,实现文字颜色自适应背景

两个案例,介绍了 CSS 相对颜色的功能。但它其实还有更为广阔的应用场景,完整的教程,你可以看这里 -- Chrome for Developers- CSS 相对颜色语法

最后

好了,本文到此结束,希望本文对你有所帮助

想 Get 到最有意思的 CSS 资讯,千万不要错过我的公众号 -- iCSS前端趣闻

更多精彩 CSS 技术文章汇总在我的 Github -- iCSS ,持续更新,欢迎点个 star 订阅收藏。

如果还有什么疑问或者建议,可以多多交流,原创文章,文笔有限,才疏学浅,文中若有不正之处,万望告知。

现代 CSS 解决方案:文字颜色自动适配背景色!的更多相关文章

  1. css Backgroud-clip (文字颜色渐变)

    首先来瞄一下background-clip,这个属性是干嘛的? 顾名思义,背景裁剪...   按照我自己的理解就是背景的显示区域 此处粘上MDN的示例链接(嫌麻烦的,后面我也贴上截图)https:// ...

  2. 【CSS】使用CSS控制文字过多自动省略号

    使用CSS可以设置一下样式: <style> u,small{ overflow: hidden; text-overflow: ellipsis; display: -webkit-bo ...

  3. CSS实现文字颜色渐变效果

    略微搜索查阅了网上的实现方法: 1.给元素添加背景渐变色,通过背景裁剪其中文字,再将文字设置为透明即可实现.(兼容性问题请自行添加浏览器前缀) background-color:linear-grad ...

  4. iOS 4s-6Plus屏幕自动适配及颜色转换为十六进制

    iOS各种屏幕自动适配及颜色转换为十六进制 ★★★XLJMatchScreen自动适配屏幕★★★ 支持pod导入 pod 'XLJScreenMatching', '~> 1.0.3' 如果发现 ...

  5. android TextView 设置部分文字背景色和文字颜色

    通过SpannableStringBuilder来实现,它就像html里边的元素改变指定文字的文字颜色或背景色 public class MainActivity extends Activity { ...

  6. css文字超出自动显示省略号

    只针对单行文本有效: 01.针对块状元素 ul li{ width: 180px; text-overflow: ellipsis; white-space: nowrap;/*禁止自动换行*/ ov ...

  7. 第四界css大会 黑魔法-css网格背景、颜色拾取器、遮罩、文字颜色渐变、标题溢出渐变等

    1.css网格背景 <!DOCTYPE html> <html lang="en"> <head> <meta charset=" ...

  8. android TextView 设置部分文字背景色 和 文字颜色

    通过SpannableStringBuilder来实现,它就像html里边的元素改变指定文字的文字颜色或背景色 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 ...

  9. 【Winform-GataGridView】根据DataGridView中的数据内容设置行的文字颜色、背景色 — 根据状态变色

    C#中可以根据每行内容的不同来对DataGridView数据表格控制每行的文字颜色.背景颜色进行不同的设置. 效果如下: 实现: 在DataGridView的RowPrePaint事件中进行行颜色控制 ...

  10. css样式重叠、css样式继承、css 属性计算,,a元素下的文字颜色不能继承

    1.属性的重叠 在渲染前浏览器将判断使用哪个样式 我们书写的样式会覆盖浏览器的自带样式 我们写的样式进行权重比较,规则如下 !import Infiniti无穷大 进制伪256行内样式 1000.id ...

随机推荐

  1. Webpack DevServer 代理本地静态目录

    前言 项目里需要离线切片地图,但切片地图文件很多,需求上有时无法单独提供一个独立的文件服务器或者切片服务器,放在 public 难免会在调试运行时被复制到 DevServer 上,而这个操作在低层级少 ...

  2. Go 函数的健壮性、panic异常处理、defer 机制

    Go 函数的健壮性.panic异常处理.defer 机制 目录 Go 函数的健壮性.panic异常处理.defer 机制 一.函数健壮性的"三不要"原则 1.1 原则一:不要相信任 ...

  3. 数据结构-线性表-顺序表(c++)

    SeqList.h #ifndef SEQLIST_H_ #define SEQLIST_H_ #include<iostream> const int Max=100; template ...

  4. [Python急救站课程]日期和时间的输出

    日期和时间的输出 from datetime import datetime # 引用datetime 库 now = datetime.now() # 获得当前日期和时间信息 print(now) ...

  5. JavaScript 语法:流程控制语句

    作者:WangMin 格言:努力做好自己喜欢的每一件事 JavaScript流程控制语句的三种基本结构:顺序结构,选择结构,循环结构 顺序结构 从上到下执行的代码就是顺序结构,程序默认就是由上到下顺序 ...

  6. Util应用框架基础(五) - 异常处理

    本节介绍Util应用框架如何处理系统错误. 概述 系统在运行过程中可能发生错误. 系统错误可以简单分为两类: 系统异常 系统本身出现的错误. 业务异常 不满足业务规则出现的错误. 如何处理系统异常 如 ...

  7. Java SPI机制学习之开发实例

    原创/朱季谦 在该文章正式开始前,先对 Java SPI是什么做一个简单的介绍. SPI,是Service Provider Interface的缩写,即服务提供者接口,它允许开发人员定义一组接口,并 ...

  8. 【随手记录】Llama Tutorial 大语言模型实践

    这个tutorial的契机是yy突然看到了一个workshop 所以类似于一周大作业的形式,输入command输出使用了自动驾驶哪些模块,代码在这里 所以就干一干,顺便写一个tutorial给大家参考 ...

  9. 关于Spring i18n国际化 报错No message found under code * for locale 'zh_CN'.的解决方案

    第一步 创建资源文件 国际化文件命名格式:基本名称 _ 语言 _ 国家.properties 这里我建了两个配置文件,一个是zh_CN中文的,一个是en_GB英文的,然后在里面随便写点测试文本语句 第 ...

  10. L2-028 秀恩爱分得快

    90行,调了俩小时,大约有以下坑点. 1.每个数字都可能正负出现,比如-0 0,-1 1,一开始以为一个数的正负只会出现一个. 2.当俩人都不出现在照片中,那么输出俩人就行 3.当其中一个人不在照片里 ...