服务粉丝

我们一直在努力
当前位置:首页 > 财经 >

Amazing!如何根据背景色自动切换黑白文字?

日期: 来源:iCSS前端趣闻收集编辑:XboxYan

在项目中,经常会碰到背景色不确定的场景,为了让内容文字足够清晰可见,文字和背景之间需要有足够的对比度。换句话说,当背景是深色时,文字为白色,当背景是浅色时,文字为黑色,就像这样:

通常这种情况,大家可能会通过 js 去计算背景色的深浅度(灰度),算法是公开的,如果已知颜色的RGB值,那么可以通过以下方式得到颜色灰度

luma = (red * 0.2126 + green * 0.7152 + blue * 0.0722) / 255

这样可以得到一个0~1之间的范围值,可以根据需求,设定一个阈值,超过表示为浅色,否则为深色。

原理就是这样,这里就不多介绍了。

那么,纯 CSS 也能实现这样的效果吗?当然可以,而且实现更简单,一起看看吧

一、CSS 滤镜实现

实现这个效果需要用到 CSS 滤镜。

假设有 HTML 是这样的

<div class="box">
  <span class="txt">前端侦探</span>
</div>

因为要使用滤镜对文字单独处理,所以需要额外一层标签。

然后,容器和文字用同一种颜色表示,目的是让文字颜色和背景相关联,可以通过currentColor实现

.box{
  color: #ffeb3b;
  background-color: currentColor;
}

接下来可以想一下,如何让彩色文字变成黑白

提到黑白,可以想到灰度滤镜(grayscale),相信大家前几天都用到过,这样可以将彩色的文字转换成灰色

.text{
  filter: grayscale(1)
}

效果如下

这样文字颜色由原来的黄绿色变成了浅灰色。

但是,这种灰色在现在这种背景下太难看清了,我们需要的是纯正的黑色或者白色,现在只是灰色,如何“加强”一下呢?

这时,我们可以用到对比度滤镜(contrast),在前面的基础上再叠加一层

.text{
  filter: grayscale(1) contrast(999)
}

这里的对比度给的比较大,这样就会极大的增强对比度,黑的更黑,白的更白,如果是浅灰,那就变成白色,如果是深灰,那就变成黑色,效果如下

这样能还不太明显,我们把背景色换一下

最后,还差一步,由于前面的操作是将原有颜色经过滤镜转换成了和自身相对应的白色或者黑色,但是是相反的,所以需要用到反转滤镜(invert),颠倒黑白

.text{
  filter: grayscale(1) contrast(999) invert(1)
}

效果如下

下面用一张图来表示转换过程

下面是任意颜色的适配效果,还是挺完美的

代码很简单,就这么一行

.text{
  filter: grayscale(1) contrast(999) invert(1)
}

完整代码可以查看以下任意链接

  • CSS auto-color (juejin.cn)[1]
  • CSS auto-color (codepen.io)[2]
  • CSS auto-color (runjs.work)[3]

二、CSS 其他思路

除了上面这种方式,还可以通过 CSS 变量来实现,要复杂一些。

这里简单介绍一下实现思路

  1. 将颜色RGB值拆分成 3 个独立的 CSS变量
  2. 通过灰度算法,用 CSS 计算函数算出灰度
  3. 用得到的灰度和阈值做差值,通过hsl模式转换成纯黑和纯白

有兴趣的可以参考张鑫旭老师的这篇文章:CSS前景背景自动配色技术简介[4],可以看到,整体实现和 js 逻辑几乎是一致的,下面是完整实现

另外可以参考之前这篇文章:CSS 变量自动变色技术

:root {
  /* 定义RGB变量 */
  --red: 44;
  --green: 135;
  --blue: 255;
  /* 文字颜色变色的临界值,建议0.5~0.6 */
  --threshold: 0.5;
}

.btn {
  /* 按钮背景色就是基本背景色 */
  background: rgb(var(--red), var(--green), var(--blue));

  /** 
   * 使用sRGB Luma方法计算灰度(可以看成亮度)
   * 算法为:
   * lightness = (red * 0.2126 + green * 0.7152 + blue * 0.0722) / 255
  */
  --r: calc(var(--red) * 0.2126);
  --g: calc(var(--green) * 0.7152);
  --b: calc(var(--blue) * 0.0722);
  --sum: calc(var(--r) + var(--g) + var(--b));
  --lightness: calc(var(--sum) / 255);
  
  /* 设置颜色 */
  color: hsl(0, 0%, calc((var(--lightness) - var(--threshold)) * -999999%));
}

效果如下

相比前面的实现而言,实现更加灵活,可以少一层标签。

另外,CSS 正在起草一个颜色对比函数color-contrast,可以从几个颜色中自动选择对比度最高的那个,实现是这样的

.text-contrast-primary {
  color: color-contrast(var(--theme-primary) vs white, black);
}

不过,现在还没有任何浏览器支持。

如果将来支持了,这将是终极解决方案。

三、优缺点总结

总的来说,在color-contrast函数支持之前,我更推荐 CSS 滤镜方式,有以下几点好处

  1. 代码简洁,就一行代码,3 个滤镜
  2. 对颜色格式无任何要求,无需转换成 RGB模式
  3. 无需了解颜色算法,对设计更为友好

当然,也是存在一些缺点

  1. 需要单独一层标签,使用场景可能有限制
  2. 对颜色敏感度较高,不然无从下手
  3. 颜色转换有限制,最终只能是黑白,其他颜色就无能为力了

下面来回顾一下用到的3个滤镜,总结一下

  1. 灰度滤镜(grayscale),可以将彩色的文字转换成灰色
  2. 对比度滤镜(contrast),可以极大的增强对比度,黑的更黑,白的更白,如果是浅灰,那就变成白色,如果是深灰,那就变成黑色
  3. 反转滤镜(invert),可以翻转颜色,颠倒黑白

重新体会颜色转换过程

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

参考资料

[1]

CSS auto-color (juejin.cn): https://code.juejin.cn/pen/7180639403566448698

[2]

CSS auto-color (codepen.io): https://codepen.io/xboxyan/pen/bGjVbGj

[3]

CSS auto-color (runjs.work): https://runjs.work/projects/bb844abe80da401d

[4]

CSS前景背景自动配色技术简介: https://www.zhangxinxu.com/wordpress/2018/11/css-background-color-font-auto-match/

如果觉得还不错,欢迎点赞、收藏、转发❤❤

相关阅读

  • 巧用视觉障眼法,还原 3D 文字特效

  • 最近群里有这样一个有意思的问题,大家在讨论,使用 CSS 3D 能否实现如下所示的效果:这里的核心难点在于,如何利用 CSS 实现一个立体的数字?CSS 能做到吗?不是特别好实现,但是,如果仅
  • 那些炫酷的 CSS 文字效果之诗词《兔》

  • 不知不觉已经迈入2023年,今年是兔年,想到兔子就会联想到玉兔,中秋,胡萝卜,兔子不吃窝边草,这就越扯越远了,今天的主题是用纯CSS来实现各种不错的文字效果,文字则摘录古诗词中有关《
  • 今晚 B 站直播预告 - 《你所不知道的CSS》

  • 扫码直达 B 站直播间,7 号晚 20:00 点准时开始,预计时长 1 小时,感兴趣来听听:Hi 各位小伙伴,本周六(2023/01/07)晚 20:00 点,我将在 Bilibili 给大家带来一场《你所不知道的CSS》
  • 不负时光,Coco 的 2022 年终总结

  • 从来没有写过年终总结,回首 2022,感觉有很多令人难忘的瞬间,觉得今年很有必要记录一下。在回家的列车上,回忆一整年的的经历,有挣扎、有坚持、有迷茫、有喜悦,最终也有收获。用文
  • CSS 奇思妙想之酷炫倒影

  • 在 CSS 中,倒影是一种比较常见的效果。今天,我们就将尝试,使用 CSS 完成各类不同的倒影效果,话不多说,直接进入主题。实现倒影的两种方式首先,快速过一下在 CSS 中,实现倒影的 2 种
  • 丢弃 HttpClient 了,这款轻量级框架更强!

  • 来自:CSDN,作者:Kevin&Amy链接:https://blog.csdn.net/qq_38233258/article/details/115799602一、Forest1.1 业务需求一般情况下是后端提供接口,前端调用,解决需求,但是有的时候为
  • Pixso插件API开放,邀你共建社区生态!

  • 随着Pixso用户的深度使用,插件广场日益活跃,设计提效相关的服务能力受到了产品团队的重视。为此,Pixso加快产品迭代,Pixso插件API正式开放啦。今天,诚挚邀请国内外优秀的开发者,加

热门文章

  • “复活”半年后 京东拍拍二手杀入公益事业

  • 京东拍拍二手“复活”半年后,杀入公益事业,试图让企业捐的赠品、家庭闲置品变成实实在在的“爱心”。 把“闲置品”变爱心 6月12日,“益心一益·守护梦想每一步”2018年四

最新文章

  • Amazing!如何根据背景色自动切换黑白文字?

  • 在项目中,经常会碰到背景色不确定的场景,为了让内容文字足够清晰可见,文字和背景之间需要有足够的对比度。换句话说,当背景是深色时,文字为白色,当背景是浅色时,文字为黑色,就像这样
  • 巧用视觉障眼法,还原 3D 文字特效

  • 最近群里有这样一个有意思的问题,大家在讨论,使用 CSS 3D 能否实现如下所示的效果:这里的核心难点在于,如何利用 CSS 实现一个立体的数字?CSS 能做到吗?不是特别好实现,但是,如果仅
  • 那些炫酷的 CSS 文字效果之诗词《兔》

  • 不知不觉已经迈入2023年,今年是兔年,想到兔子就会联想到玉兔,中秋,胡萝卜,兔子不吃窝边草,这就越扯越远了,今天的主题是用纯CSS来实现各种不错的文字效果,文字则摘录古诗词中有关《
  • 今晚 B 站直播预告 - 《你所不知道的CSS》

  • 扫码直达 B 站直播间,7 号晚 20:00 点准时开始,预计时长 1 小时,感兴趣来听听:Hi 各位小伙伴,本周六(2023/01/07)晚 20:00 点,我将在 Bilibili 给大家带来一场《你所不知道的CSS》
  • 不负时光,Coco 的 2022 年终总结

  • 从来没有写过年终总结,回首 2022,感觉有很多令人难忘的瞬间,觉得今年很有必要记录一下。在回家的列车上,回忆一整年的的经历,有挣扎、有坚持、有迷茫、有喜悦,最终也有收获。用文
  • CSS 奇思妙想之酷炫倒影

  • 在 CSS 中,倒影是一种比较常见的效果。今天,我们就将尝试,使用 CSS 完成各类不同的倒影效果,话不多说,直接进入主题。实现倒影的两种方式首先,快速过一下在 CSS 中,实现倒影的 2 种