当前位置主页 > 资料库 > 前端教程 > 如何制作平滑的“box-shadow”盒子阴影动画效果

如何制作平滑的“box-shadow”盒子阴影动画效果

2016-01-19

在我们制作box-shadow属性的动画的时候,每一帧动画都会引起浏览器的重绘操作,严重影响页面的性能。我们有什么办法可以解决动画box-shadow属性时页面的性能问题呢?答案是:没有!但是我们可以使用其它方法来模拟box-shadow动画:通过动画伪元素的opacity属性来达到动画元素阴影的效果。通过这种方法只需要进行少量的重绘,就可以达到和动画box-shadow属性一样的效果。

使用box-shadow属性来制作元素的阴影动画效果。

动画box-shadow属性

使用鼠标滑过卡片看看效果

使用动画来改变box-shadow (在这个例子中从 box-shadow: 0 1px 2px rgba(0,0,0,0.15)box-shadow: 0 5px 15px rgba(0,0,0,0.3)的过程中会一起每一帧都进行重绘操作。

也许在你的桌面电脑浏览器中不会看出有什么问题,但是在移动手机上就有可能会出现问题。也许在更为复杂的布局中,你的桌面电脑浏览器也会出现问题。

使用伪元素来制作元素的阴影动画效果。

使用伪元素动画进行模拟

使用鼠标滑过卡片看看效果

我们可以通过插入一个:after来减少重绘的数量,同时为它添加一个阴影,然后在鼠标滑过时动画伪元素的opacity属性。

transformopacity属性的修改都是被硬件加速的,所以我们可以达到更好的性能效果。

在执行上面的两个例子的时候,打开你的浏览器开发人员工具,你可以看到类似下面的结果:

元素的阴影动画效果的性能比较

从上图可以看到,直接使用box-shadow属性进行动画会进行更多的重绘操作。

opacitytransform属性是少数执行动画时不进行重绘操作的CSS属性之一。所以我们通过结合这两个属性可以达到性能优化的效果。

上面两种阴影动画效果的核心实现代码如下:

/* box-shadow动画 */
.make-it-slow {
  box-shadow: 0 1px 2px rgba(0,0,0,0.15);
  transition: box-shadow 0.3s ease-in-out:
}

/* 在鼠标滑过时过渡到一个较大的阴影 */
.make-it-slow:hover {
  box-shadow: 0 5px 15px rgba(0,0,0,0.3);
}

/* 伪元素阴影效果 */
.make-it-fast {
  box-shadow: 0 1px 2px rgba(0,0,0,0.15);
}

/* 重新渲染较大的阴影,同时将阴影隐藏 */
.make-it-fast::after {
  box-shadow: 0 5px 15px rgba(0,0,0,0.3);
  opacity: 0;
  transition: opacity 0.3s ease-in-out:
}

/* 在鼠标滑过时显示较大的阴影 */
.make-it-fast:hover::after {
  opacity: 1;
}                            
                        
使用伪元素实现元素阴影动画效果

使用伪元素实现元素阴影动画效果的完整过程也非常简单。首先我们需要使用:after伪元素来制作元素鼠标滑过时的大阴影效果。例如我们需要为一个<div>元素制作阴影动画效果。

<div class="box"></div>                            
                        
/* 为div元素创建简单的CSS样式,为它添加一个阴影效果 */
.box {
  position: relative;
  display: inline-block;
  width: 100px;
  height: 100px;
  border-radius: 5px;
  background-color: #fff;
  box-shadow: 0 1px 2px rgba(0,0,0,0.15);
  transition: all 0.3s ease-in-out;
}

/* 插件伪元素并隐藏它 */
/* 注意box-shadow属性的设置 */
.box::after {
  content: '';
  position: absolute;
  z-index: -1;
  width: 100%;
  height: 100%;
  opacity: 0;
  border-radius: 5px;
  box-shadow: 0 5px 15px rgba(0,0,0,0.3);
  transition: opacity 0.3s ease-in-out;
}                            
                        

由于我们需要同时动画div元素和它的伪元素的opacity属性,所以为这两个元素都添加了transition动画过渡效果。

通过上面的设置,我们得到了一个带阴影效果的矩形,它的大阴影开始时是隐藏的,得到的结果类似下面的样子:

接下来我们开始制作鼠标滑过时的阴影动画效果。在鼠标滑过div元素时将它放大,然后将它的伪元素的透明度从0过渡到1。

/* 放大div元素 */
.box:hover {
  transform: scale(1.2, 1.2);
}

/* 将伪元素的透明度从0修改为1 */
.box:hover::after {
  opacity: 1;
}                            
                        

到此我们就得到了鼠标滑过时的阴影动画效果。用鼠标滑过下面的div看看效果。

下面是完整的使用伪元素实现元素阴影动画效果的CSS样式代码,包括各个浏览器厂商的前缀。

.box {
  position: relative;
  display: inline-block;
  width: 100px;
  height: 100px;
  background-color: #fff;
  border-radius: 5px;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
  border-radius: 5px;
  -webkit-transition: all 0.6s cubic-bezier(0.165, 0.84, 0.44, 1);
  transition: all 0.6s cubic-bezier(0.165, 0.84, 0.44, 1);
}

.box::after {
  content: "";
  border-radius: 5px;
  position: absolute;
  z-index: -1;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
  opacity: 0;
  -webkit-transition: all 0.6s cubic-bezier(0.165, 0.84, 0.44, 1);
  transition: all 0.6s cubic-bezier(0.165, 0.84, 0.44, 1);
}

.box:hover {
  -webkit-transform: scale(1.25, 1.25);
  transform: scale(1.25, 1.25);
}

.box:hover::after {
    opacity: 1;
}                            
                        

通过动画transformopacity属性,我们可以得到更好的性能效果。所以,在你以后要制作类似的盒子阴影动画效果的时候,请不要直接动画box-shadow属性,而应该采用本文介绍的方法。

Previous:
上一篇:深入理解SVG描边(stroke)属性
Next:
下一篇:打造与众不同的鼠标滑过超链接下划线动画效果
返回顶部