乐趣区

关于前端:CSS-颜色混合的N种方式

欢送关注我的公众号:前端侦探

在我的项目中常常会碰到须要邻近色的场景,比方将一个色彩变深(浅)一点,上面是一个按钮的选中态

如果呈现一种色彩就定义一个变量,每次都要保护多个色彩变量太麻烦了。有没有方法只用一个色彩呢?在这里也就是,如何将一个色彩变浅一点?这样做的益处是,如果须要更换主题色,只用批改一个变量就行了,如下

上面盘点我用过的一些办法

一、透明度

这应该是最容易想到的形式。将一个元素透明度升高不就色彩变浅了吗?

假如 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-shadowoutline 这些就不行,这些属性没法叠加多层背景。

三、动画

这个形式在之前这篇文章中有具体介绍:

妙用 CSS 动画来实现色彩加深、减淡等混合操作

次要原理是 动画播放次数也是反对小数的 ,比方设置一个从蓝色到红色的动画,播放次数为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)

@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()

这个算是官网的解决方案了,如果这个广泛反对了,后面的办法都能够不必了,上面简略介绍一下

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 (codepen.io)
  • CSS color lighter (runjs.work)

六、总结一下优缺点

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

  • 实现老本:实现思路的复杂度,是否容易想到
  • 适应性:是否适应各种场景
  • 代码复用性:实现是否啰嗦,是否须要额定标签
  • 兼容性:是否大规模应用
实现老本 适应性 代码复用性 兼容性
透明度 ⭐️(低) ⭐️(差) ⭐️(低) ⭐️⭐️⭐️(好)
多重背景 ⭐️ ⭐️ ⭐️ ⭐️⭐️⭐️
动画 ⭐️⭐️⭐️(高) ⭐️⭐️ ⭐️⭐️ ⭐️⭐️⭐️
自定义属性动画 ⭐️⭐️ ⭐️⭐️⭐️(强) ⭐️⭐️⭐️ ⭐️⭐️
color-mix ⭐️ ⭐️⭐️⭐️ ⭐️⭐️⭐️(高) ⭐️(差)

总的来说,自定义属性动画 在各方面是比拟举荐的,如果不思考 firefox 的话根本能够放心使用了,其余形式也能够依据理论需要自行抉择,哪个不便用哪个。

最初,如果感觉还不错,对你有帮忙的话,欢送 点赞、珍藏、转发❤❤❤

欢送关注我的公众号:前端侦探

本文参加了 SegmentFault 思否写作挑战赛,欢送正在浏览的你也退出。

退出移动版