换个方法,或许效果会更好

前言

自打从人类逆向进化为程序猿,每当进入某个网页后,第一眼关注的是网页的设计、体验、性能,而不是关注内容,遇到交互酷炫、使用流畅的网页,都会久久驻足啧啧称赞,打开调试框,看看这个CSS是如何实现的,相信很多前端小伙伴都和我有类似的习惯。好啦,废话不多说,进入正题,今天我们探索的是一个功能简单,但是有着不同体验的效果CSS动效。

主题

今天的主题是我在很多文档或者官网上看到的一个CSS动效样式,如图(加载稍慢):
image
那么,这种效果是怎么实现的呢?于是好奇宝宝开始了今天的探索~

远古时代

当然,第一种想到的办法就是:hover伪类从黑白图片切换一个彩色的background-image,好像是这样可以的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<style>
.box {
height: 126px;
width: 390px;
display: inline-block;
background-size: cover;
background-position: center;
}
.bg1 {
background-image: url('http://p0ml8s4qd.bkt.clouddn.com/bgblack.png')
}
.bg1:hover{
background-image: url('http://p0ml8s4qd.bkt.clouddn.com/bgcolor.png')
}
.bg2 {
background-image: url('http://p0ml8s4qd.bkt.clouddn.com/bg2black.jpg')
}
.bg2:hover{
background-image: url('http://p0ml8s4qd.bkt.clouddn.com/bg2color.png')
}
</style>
<body>
<div class="bg1 box"></div>
<div class="bg2 box"></div>
</body>

如图效果:

image

蓝鹅。。。好像并不是这样的,当鼠标移动过去的时候,会出现闪动的bug,体验及其不好,分析下,原来当:hover的background-image还未“触发”的时候,彩色图片是不会加载的,因此,这个闪动的过程就是图片加载的过程,那么有没有别的方案来解决这个问题呢?

这个时候,我们是不是想到可以使用图片预加载的方案来解决?试一试~

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<style>
.box {
height: 126px;
width: 390px;
display: inline-block;
background-size: cover;
background-position: center;
}
.test {
position: absolute;
top: -9999px;
background-image: url('http://p0ml8s4qd.bkt.clouddn.com/bgcolor.png');
}
.test2 {
position: absolute;
top: -9999px;
background-image: url('http://p0ml8s4qd.bkt.clouddn.com/bg2color.png');
}
//...其他样式
}
</style>
<body>
<div class="test"></div>
<div class="test2"></div>
<div class="bg1 box"></div>
<div class="bg2 box"></div>
</body>

我们提前加载这些图片,那么就能够解决这个问题啦,但是还是很麻烦,不够优雅,对DOM有着很强的入侵性。再来想想有没有更好的方法~

民国时代

那么我们如何来解决上面的这种问题呢,如何才能更优雅地解决这个问题呢~,之前写过一篇关于 background-position的文章,我们是否能够通过一张含有两种(黑白、彩色)图片,然后切换position来动态更换background呢?试一试~

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<style>
.box {
height: 209px;
width: 650px;
display: inline-block;
background-size: cover;
background-image: url('http://p0ml8s4qd.bkt.clouddn.com/download.png');
background-position: -5px -5px;
}
.box:hover{
background-position: -5px -220px;
}
</style>
<body>
<div class="box"></div>
</body>

如图:

image

这里我们似乎成功了,不过我们仔细看,当鼠标移过去时,会有轻微的抖动,有的时候,通过调整background-position是无法精确地合并,并且这种方案需要去手动地拼合图片,然后在css上又要手动调整position,甚是麻烦,肯定还有更好的解决方案~

建国时代

我们可以使用CSS3 filter(滤镜)属性,它包含很多处理图片的属性值,就像ps上面的各种滤镜,我们用来grayscale(灰度)这个属性值切换图片的黑白,这么说,我们来试试~

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<style>
.box {
height: 209px;
width: 650px;
display: inline-block;
background-size: cover;
background-image: url('http://p0ml8s4qd.bkt.clouddn.com/bg2color.png');
background-position: center;
filter: grayscale(100%)
}
.box:hover{
filter: grayscale(0);
}
</style>
<body>
<div class="box"></div>
</body>

如图:

image

这样我们就很优雅的完成了这个效果,这种方法实现简单,不需要各种手动配置,体验也很优良,很遗憾的是,万恶的IE浏览器支持度并不高,我们来看看支持程度(截至2018年6月):
image

总结

这次探索虽然并不是很高深的知识,不同的实现方式有着不同的用户体验和实现复杂度,并且也有着对应的兼容性,我们能做的是,在满足大部分的兼容性条件下,实现更好的用户体验效果。在我看来,本次主题的最佳实践方案,还是第一种的“远古时代”方案,虽然书写复杂点,但是兼容性好,用户体验也不错。好啦,本次探索到这里,文章如有错误欢迎指正~

Truth never fears investigation.