如果出现一种颜色就定义一个变量,每次都要维护多个颜色变量太麻烦了。有没有办法只用一个颜色呢?在这里也就是,如何将一个颜色变浅一点?这样做的好处是,如果需要更换主题色,只用修改一个变量就行了。

在项目中经常会碰到需要邻近色的场景,比如将一个颜色变深(浅)一点,下面是一个按钮的选中态

如果出现一种颜色就定义一个变量,每次都要维护多个颜色变量太麻烦了。有没有办法只用一个颜色呢?在这里也就是,如何将一个颜色变浅一点?这样做的好处是,如果需要更换主题色,只用修改一个变量就行了,如下:

下面盘点我用过的一些方法。

一、透明度

这应该是最容易想到的方式。将一个元素透明度降低不就颜色变浅了吗?

假设 HTML是这样的(下同)。

<button style="--primary-color: #3981E6">#3981E6</button>

不过这种方式需要借助单独一层标签,通常可以用伪元素生成,关键实现如下:

button::before{content: '';background: var(--primary-color);opacity: 0.2
}

效果还是非常不错的,下面是多种主题色的效果。

不过这种方式也有局限,比如伪元素不够用怎么办?还有绝对定位引起的层级问题。

没关系,还有其他方式,接着往下看。

二、多重背景

大家可能都知道,CSS3 背景是支持多重背景的,并且层级是越来越低的。

因此,我们可以在主题色上覆盖一层半透明的白色,依然可以将原有颜色“减淡”。

由于这里是背景图,所以需要用到渐变,而不是颜色。比如希望主题色减淡到自身的20%​,可以覆盖80%透明度的白色,实现如下:

button{background: linear-gradient(rgba(255,255,255,.8),rgba(255,255,255,.8)), /*半透明白色*/linear-gradient(var(--primary-color), var(--primary-color));
}

这样就无需借助额外的标签或者伪元素了,效果如下:

不过这种方式也有一些缺陷,比如仅适合背景层,如果希望box-shadow、outline这些就不行,这些属性没法叠加多层背景。

三、动画

主要原理是动画播放次数也是支持小数的,比如设置一个从蓝色到白色的动画,播放次数为​​0.8​​​,那么在播放到​​80%​​的地方就停下来了,这样就得到了颜色减淡的效果,示意如下:

具体实现如下:

button{animation: lighterBackgroundColor .001s 0.8 linear forwards;/*播放次数为0.8*/
}
@keyframes lighterBackgroundColor {from {background-color: var(--primary-color)}to{background-color: #fff}
}

效果也很棒。

相比前一种方式,就没有背景的限制了,任意属性都可以,但是每出现一个属性就需要单独一个动画(因为动画变化的就是属性本身),如果要加一个减淡后的outline-color,应该要这么实现。

button{animation: lighterBackgroundColor .001s 0.8 linear forwards, lighterOutlineColor .001s 0.8 linear forwards; /*outline*//*播放次数为0.8*/
}
@keyframes lighterBackgroundColor {from {background-color: var(--primary-color)}to{background-color: #fff}
}
/*设置一个outline的动画*/
@keyframes lighterOutlineColor {from {outline-color: var(--primary-color)}to{outline-color: #fff}
}

太繁琐了,有没有简单一点的方法呢?

四、自定义属性动画

上面将属性作为动画有点浪费,因为变化值都是一样的,有没有办法复用呢?

当然可以,将 CSS 变量作为动画对象,比如--lighterColor。

button{animation: lighterColor .001s 0.8 linear forwards;/*播放次数为0.8*/
}
@keyframes lighterColor {from {--lighterColor: var(--primary-color)}to{--lighterColor: #fff}
}

但是,仅仅这样是不够的,动画并不认识这样的变量,根本不会有动画(就像display一样)。

为了让自定义变量也支持动画,需要通过@property定义一下。

@property - CSS:层叠样式表 | MDN (mozilla.org)[1]​。

@property --lighterColor {syntax: '<color>';inherits: false;initial-value: #fff;
}

相比前面的方式,但是适用性更佳,--lighterColor​已经是一个独立的变量了,可以用在任意属性上,比如加个outline。

button{background-color: var(--lighterColor);outline: 4px solid var(--lighterColor);
}

可以看到,outline也轻易地实现了颜色减淡。

缺点就是,兼容性欠佳,目前firefox还不支持

五、color-mix()

最后介绍一个最近正式支持(Chrome 110+)的颜色混合函数:color-mix()[2]。

这个算是官方的解决方案了,如果这个普遍支持了,前面的方法都可以不用了,下面简单介绍一下。

color-mix(in lch, peru 40%, lightgoldenrod);
color-mix(in srgb, #34c9eb 20%, white);

前面的in lch​表示色彩空间,我们一般只用srgb就足够了,后面的两个颜色就需要混合的颜色了。

这里的百分比就是混合比例了,如果我们要实现减淡80%​的操作,可以将主题色的比例设置为20%,白色会自动填充剩余比例,如下:

button{--lighterColor: color-mix(in srgb, var(--primary-color) 20%, #fff);background-color: var(--lighterColor);outline: 4px solid var(--lighterColor);
}

效果如下(Chrome 110+)。

目前还不适合使用,过两年再说吧。

下面是所有方案的效果对比,基本是一致的。

完整 demo 可以访问以下任意链接:

  • CSS color lighter (juejin.cn)[3]
  • CSS color lighter (codepen.io)[4]
  • CSS color lighter (runjs.work)[5]

六、总结一下优缺点

以上共介绍了5种不同的颜色混合实现方式,各有优缺点,下面分别从以下几个方面比较一下

  • 实现成本:实现思路的复杂度,是否容易想到。
  • 适应性:能否适应各种场景。
  • 代码复用性:实现是否啰嗦,是否需要额外标签。
  • 兼容性:能否大规模使用。

实现成本

适应性

代码复用性

兼容性

透明度

⭐️(低)

⭐️(差)

⭐️(低)

⭐️⭐️⭐️(好)

多重背景

⭐️

⭐️

⭐️

⭐️⭐️⭐️

动画

⭐️⭐️⭐️(高)

⭐️⭐️

⭐️⭐️

⭐️⭐️⭐️

自定义属性动画

⭐️⭐️

⭐️⭐️⭐️(强)

⭐️⭐️⭐️

⭐️⭐️

color-mix

⭐️

⭐️⭐️⭐️

⭐️⭐️⭐️(高)

⭐️(差)

总的来说,自定义属性动画在各方面是比较推荐的,如果不考虑firefox的话基本可以放心使用了,其他方式也可以根据实际需求自行选择,哪个方便用哪个。

参考资料

[1]@property - CSS:层叠样式表 | MDN (mozilla.org): https://developer.mozilla.org/zh-CN/docs/Web/CSS/@property​。

[2]color-mix(): https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/color-mix​。

[3]CSS color lighter (juejin.cn): https://code.juejin.cn/pen/7206605166953365563​。

[4]CSS color lighter (codepen.io): https://codepen.io/xboxyan/pen/dyqRyVG​。

[5]CSS color lighter (runjs.work): https://runjs.work/projects/91dcf9cdd9f7447b​。

CSS 颜色混合的N种方式相关推荐

  1. 网页设计的css样式,网页设计引入CSS样式的五种方式_css

    一.使用STYLE属性 将STYLE属性直接加在个别的元件标签里,<元件(标签) STYLE="性质(属性)1: 设定值1; 性质(属性)2: 设定值2; -} 例如: <TD ...

  2. HTML 引用Css样式的四种方式

    不才,只知道HTML引用CSS样式有四种方式,内部引用和外部引用各两种,因为老是忘记细节,记下了随时翻阅亦可方便如我般的初学者 内部引用方式1: 直接在标签内用 style 引用,如: <div ...

  3. html中引入css样式表的三种方式,css引用的几种方式是什么?

    HTML怎么引用CSS样式?css引用的几种方式是什么?下面本篇文章就来给大家介绍一下在HTML中引用CSS样式的几种方法,希望对大家有所帮助. 1.行内式 在HTML标签中,使用style属性设置C ...

  4. 原生js更改html,原生js更改css样式的两种方式

    原生js更改css样式的两种方式 发布时间:2020-08-30 01:46:17 来源:脚本之家 阅读:148 作者:外婆的彭湖湾 下面我给大家介绍的是原生js更改CSS样式的两种方式: 1. 通过 ...

  5. 重学前端第一阶段完 钢琴项目(document.querySelector js改变css样式的3种方式 思路 成品)

    菜鸟学完之后,总是感觉学了也还是不会,主要就是因为没有实践,不知道自己到底哪里有问题!虽然说我还没复习完,前端很大一部分都处于模糊阶段,但是感觉还是应该先尽力做一个简单的东西,把这几天学的都用进去,遇 ...

  6. JS设置CSS样式的几种方式(js设置!important)

    JS设置CSS样式的几种方式(js设置!important) x619y 用JS来动态设置CSS样式,常见的有以下几种 1. 直接设置style的属性  某些情况用这个设置 !important值无效 ...

  7. JS设置CSS样式的几种方式

    JS设置CSS样式的几种方式 1.直接设置style的属性 某些情况下用这个设置!import值无效 如果属性有"-"号,就需要使用驼峰命名法(如textAlign),如果想保留& ...

  8. html js 设置样式,原生js设置样式 笔记:JS设置CSS样式的几种方式

    document(id名).style.backgroundColor = "ren" css里的属性有-的就去掉将首字母大写. js如何添加CSS样式中的class添加属性 用J ...

  9. 创建CSS样式的三种方式

    CSS基础 - 创建CSS样式的三种方式 我们使用CSS的时候,常规有三种创建CSS样式的的方式: 内联样式,内部样式表,外部样式表 1.内联样式 (不常用) style在标签中的情况就是内联样式.不 ...

最新文章

  1. 我的WCF之旅(6):在Winform Application中调用Duplex Service出现TimeoutException的原因和解决方案...
  2. java用重载实现获取元素的数据类型
  3. python 基础教程:字符串内建函数之大小写的区别
  4. 二叉搜索树的经典问题
  5. openresty配置部署
  6. XMPP聊天之Openfire 的安装和配置---Mac OS
  7. 520 钻石争霸赛 7-6 矩阵列平移(循环)
  8. Linux Kernel系列 - 黄牛X内核代码凝视
  9. php 调用带返回多个结果集的方法,PHP中有多个结果集?
  10. windows中python虚拟环境_Windows下Python虚拟环境的配置
  11. 计算机科学和机器学习中的代数、拓扑、微积分和最优化理论
  12. ESP8266——入门:点亮TFT液晶屏(五)
  13. Django:get() returned more than one Session -- it returned 8
  14. 修改植物大战僵尸游戏存档相关知识
  15. jQuery开发经验实例笔记
  16. IAM统一身份认证服务
  17. WinRAR(去广告)中文繁体
  18. div 设置a4大小_网页打印时设置A4大小
  19. 【干货来袭】arm程序汇编指令总结,让你更高效的学习!
  20. 黑客攻防技术宝典(一)

热门文章

  1. 电子负载和电池容量测试仪概念误区
  2. 洋桃项目组-人机交互界面项目(仅参考)
  3. ubuntu18.04创建新用户
  4. win10任务管理器快捷键_Win10全新任务管理器上线:专为PC游戏优化-Windows 10,微软,PC游戏 ——快科技(驱动之家旗下媒体)-...
  5. 优秀有价值的博客收藏列表
  6. 揭秘Redis持久化原理,探索fork与Copy-on-Write的魔法!
  7. Golang中的一些关键字(defer、:=、go func())
  8. android 矢量粒子动画,iOS CAEmitterLayer实现粒子发射动画效果
  9. js 前端根据多个条件筛选过滤数据
  10. 第五代脉冲电子围栏领衔周界安防行业大变革