欢迎关注我的公众号:前端侦探
今天来介绍一下 Chrome 111+
正式推出的 CSS颜色混合函数:color-mix()。
所谓颜色混合,顾名思义,就是将两种颜色按照一定的比例混合起来,和调色板比较像。到目前为止,可以说是最强大、最实用的 CSS 颜色处理函数了,有了它,再也不需要用LESS
、SASS
等预处理工具了,还可以实现颜色动态更新,一起了解一下吧
一、color-mix语法
首先来看语法,比较简单
color-mix(in lch, plum, pink);
color-mix(in lch, plum 40%, pink);
color-mix(in srgb, #34c9eb 20%, white);
color-mix(in hsl longer hue, hsl(120 100% 50%) 20%, white);
通用语法写作
color-mix(method, color1[ p1], color2[ p2])
主要由 3 部分组成,分别是插值颜色法(method
,这里只介绍颜色空间)、基础颜色(color1
)和混合颜色(color2
),示意如下
颜色空间是一个很复杂的概念,这里不做介绍,只需要知道用法就行。
- 矩形颜色空间。
srgb
、srgb-linear
、lab
、oklab
、xyz
、xyz-d50
、xyz-d65
- 极性颜色空间 。
hsl
、hwb
、lch
、oklch
以红色和白色混合为例
color-mix(in srgb, red, white);
下面是实际混合效果
可以看到,混合后的颜色介于红色和白色的中间,相当于把之前的颜色减淡了。
再比如,红色和黄色混合,可以得到橙色
color-mix(in srgb, red, yellow);
效果如下
这是如何混合的呢,很简单,以rgb
为例,其实就是将对应的值取平均数
R = (r1 + r2)/ 2
G = (g1 + g2)/ 2
B = (b1 + b2)/ 2
比如红色是rgb(255,0,0)
,黄色是rgb(255,255,0)
,计算如下
R = (255 + 255)/ 2 = 255
G = (0 + 255)/ 2 = 127.5
B = (0 + 0)/ 2 = 0
所以混合的颜色就是rgb(255,127.5,0)
,也就是橙色
你也可以在下面的 demo 中自行调整颜色体验
这应该就是颜色混合最直观的认识了。
二、 color-mix 混合比例
当然,这只是最简单的情况。在上面的语法中,还可以给颜色设置混合比例,也就是前面语法中的p1
和p2
。
color-mix(method, color1[ p1], color2[ p2])
由于 CSS 强大的“包容”性,对各种情况都做了兼容,主要分为以下几种情况
- 如果 和
p1
都p2
被省略,则p1 = p2 = 50%
- 如果
p1
省略,则p1 = 100% - p2
- 如果
p2
省略,则p2 = 100% - p1
- 如果
p1 = p2 = 0%
,则该函数无效 - 如果
p1 + p2 ≠ 100%
,则p1' = p1 / (p1 + p2)
和p2' = p2 / (p1 + p2)
,其中p1'
和p2'
是归一化结果
前面 4 种情况都比较好理解,就是互相补全,另外注意,这两个值都位于0%~100%
,超出范围者直接不合法
下面来看最后一种情况,也就是两者相加不等于100%
的情况。
这里其实也要分两种,首先是p1+p2>100%
的情况,比如
color-mix(in srgb, red 100%, white 100%);
这种混合应该怎么计算呢?
首先还是按照上面的计算规则,算出两者的比例关系
p1' = p1 / (p1 + p2) = 100% / (100% + 100%) = 0.5
p2' = p1 / (p1 + p2) = 100% / (100% + 100%) = 0.5
也就是两者是1:1
混合的,在超过100%
的情况下,仍然按照100%
进行分配,也就是等同于
color-mix(in srgb, red 100%, white 100%);
/* 等同于 */
color-mix(in srgb, red 50%, white 50%);
效果如下
同理,这种情况下也是等同的,因为都是 4:1
color-mix(in srgb, red 100%, white 25%);
/* 等同于 */
color-mix(in srgb, red 80%, white 20%);
效果如下
所以,在两者相加大于100%
的情况下,可以先计算两者的比例,然后再用100%
按比例分配即可。
然后是p1+p2<100%
的情况。
起初,我以为也是相同的处理方式,其实不然。以下面这个为例
color-mix(in srgb, red 20%, white 20%);
/* 等同于? */
color-mix(in srgb, red 50%, white 50%);
混合比例其实都是1:1
,最后这两者结果会相同吗?可以先看结果
可以明显看到,下面的混合结果颜色跟淡一些。为什么呢,其实可以从最终的混合颜色看出原因,这里直接通过控制台来得到计算颜色,如下
两个实色混合出来居然有了透明度!
这个透明度怎么来的呢?其实就是由于两者混合相加不足100%
,刚才这个例子,两者相加20%+20%=40%
,所以最终的混合出现了0.4
的透明度。
我们再换个例子
color-mix(in srgb, red 40%, white 10%);
/*等同于*/
color-mix(in srgb, red 80%, white 20%); /* 50%透明度 */
效果如下
从控制台可以看到,刚好就是50%
的透明度
因此,在两者相加小于100%
的情况下,可以先计算两者的比例,然后再按比例分配,最后再叠加上透明度。这样看来,其实大于100%
的情况也可以理解为叠加了一个大于1
的透明度,只不过最后解析成了1
。
三、color-mix 实际应用
使用color-mix
可以很方便的根据主题色生成与之相对应的邻近色,例如
:root{
--primary-color: #ffeb3b;
--primary-secondary-1: color-mix(in srgb, var(--primary-color), #fff 20%);
--primary-secondary-2: color-mix(in srgb, var(--primary-color), #fff 40%);
--primary-secondary-3: color-mix(in srgb, var(--primary-color), #fff 60%);
--primary-secondary-4: color-mix(in srgb, var(--primary-color), #fff 80%);
}
效果如下
这样在实现一些跟随主题色变化的按钮就非常方便了
button{
color: var(--primary-color);
background-color: var(--primary-secondary-4);
outline: 4px solid var(--primary-secondary-4);
}
效果如下
这些技巧在之前这些文章中都有介绍,还提供了其他解决方案,如果不考虑兼容性,color-mix
无疑是最方便的
四、兼容性和回退措施
兼容性文章开头就有提到,完整兼容性如下
现在主流浏览器已经全部兼容了,放心学习吧。
不过实际工作中,还需要做好回退措施,如果浏览器不兼容怎么办?有些同学可能会想到用 CSS 变量来做回退处理,如下
div{
--bg: color-mix(in srgb, red, blue);
background: var(--bg, var(--fallback-color));
}
很可惜,这种方式并不可取。原因在于,CSS 变量只有在未定义时,才会走后面的回退值。这种情况下,仍然取前面的值,从而导致颜色失效。
正确的做法是使用CSS supports
进行判断
:root{
--bg: orange
}
@supports (color:color-mix(in srgb,red,blue)) {
--bg: color-mix(in srgb, red, blue);
}
这样,在不支持的浏览器中也能使用一个还能接受的回退值,只是不能动态去混合了
五、总结一下
以上就是本文的全部内容了,相信你会对颜色混合有更深刻的理解,下面总结一下
color-mix
其实就是将两种颜色按照一定的比例混合起来,和调色板比较像- 语法很简单,只有3个参数,分别是插值颜色法(
method
)、基础颜色(color1
)和混合颜色(color2
) - 插值颜色法可以先不用管,一般用来定义颜色空间,有 hsl、srgb
- 两种颜色混合可以设置混合比例,由于 CSS 强大的“包容”性,对各种情况都做了兼容
- 在混合比例在两者相加大于
100%
的情况下,需要先计算两者的比例,然后再用100%
按比例分配。 - 在混合比例在两者相加小于
100%
的情况下,会出现透明度 - 颜色混合最常见的用途是根据主题色生成与之相对应的邻近色
- 目前主流浏览器全兼容,在实际开发中,需要使用
CSS supports
进行回退处理
CSS 颜色处理函数真的是越来越强大了,后面还会介绍其他比较实用的颜色函数。最后,如果觉得还不错,对你有帮助的话,欢迎点赞、收藏、转发❤❤❤
欢迎关注我的公众号:前端侦探
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。