三年前有写过关于小图标变色的文章,参见:"纯CSS实现任意格式图标变色的研究",这篇文章更多的是研究性质,而本文就属于结论,多年实践下来的经验分享。
一、最好方法是mask遮罩
小图标变色最好的方法一定是遮罩,兼容性好,适应性强(-webkit-
私有前缀略)。
.icon {
color: deepskyblue;
background-color: currentColor;
mask: url(./icon.svg) no-repeat center / 100%;
}
此时通过改变图标的 color
颜色值,就能有变色效果了。
眼见为实,您可以狠狠地点击这里:CSS mask遮罩实现任意颜色的小图标demo
但是实际开发的时候,有时候小图标不能作为单独的元素使用(包括 CSS 伪元素),此时使用遮罩就有问题,例如有个 <input>
搜索框,里面有个图标:
此时使用遮罩就会有问题,因为会把边框一起遮罩掉(如果没有圆角,技术上是可以模拟的),那有没有什么办法不使用两个图标素材依然实现图标的变色效果呢?
二、背景混合模式技术
我目前探索出来可行的方法就是背景混合模式 background-blend-mode
属性。
实现的固定套路是这样的:
/* 变色的时候改变 --fill-color 的属性值 */
.element {
--fill-color: gray;
background: linear-gradient(var(--fill-color), var(--fill-color)), url(./icon.svg), #fff;
/* 或者 lighten, normal; */
background-blend-mode: screen, normal;
}
通过改变 CSS 自定义属性 --fill-color
的值就可以实现图标的变色了。
测试下来,如果 icon.svg 图标有很多半透明的边缘像素点,screen
混合模式效果更好,如果底色不是白色,而是很淡的灰色,则screen 混合效果会有些许误差,lighten 效果没有误差。
screen 这种混合模式表示滤色,在 Web 开发中还比较常用,相关介绍可以参见这篇文章"深入理解CSS mix-blend-mode滤色screen混合模式"。
一些限制
- icon.svg 需要是纯黑色,这个很好满足,大多数小图标网站下载的纯色图标默认都是黑色;
- 元素背景不需要是透明;
此方法实现的前提是元素需要设置一个浅色的底色,不然混合模式的执行就会有问题,因此,适合有背景色也无关紧要的场景,例如像是搜索框这种,就非常合适。
案例演示
您可以狠狠地点击这里:CSS背景小图标变色demo
实际的变色效果 MP4 录屏示意(不动点击播放):
可以看到,无论设置什么颜色,图标的颜色都会跟着一起变化。
实现原理
参见这篇文章:"深入理解CSS background-blend-mode的作用机制",和元素混合模式属性 mix-blend-mode
的渲染还是有些区别的。
三、新年快乐,虎年吉祥
今天大年30,还有半个小时就虎年了,本命年到了,时间过得好快,也是大叔级别的人了。
祝大家新的一年,怎么讲呢,努力的付出都有回报吧。
另外,本文的实现不一定是最好的方法,如果您有很好的思路,欢迎分享。
(本篇完)