本技巧来自这篇文章 -- How to animate box-shadow with silky smooth performance

本文不是直译,因为觉得这个技巧很有意思很有用,遂起一文。

box-shadow 在我们的工作中使用以及越来越多,伴随阴影的动画或多或少都有一点。假设,我们有下面这样一个盒子:

div {
width: 100px;
height: 100px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
}

希望 hover 的时候,盒阴影从 box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3) 过渡到 box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3)

  • box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3) --> box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3)

OK,最简单的方法当然是:

div:hover {
width: 100px;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
}

因为过渡动画是在两个不同的盒阴影状态在发生,所以在过渡动画的时间内,浏览器会不断的重绘盒阴影。而又由于阴影属于耗性能样式,所以这种动画给人的感觉多少有些卡顿。

这里有一个小技巧可以优化这种情况下的阴影动画。

使用伪元素及透明度进行优化

使用伪元素及透明度进行优化,我们给上述元素添加一个 before 伪元素,大小与父 div 一致,并且提前给这个元素添加好所需要的最终的盒阴影状态,但是元素的透明度为 0。

div {
position: relative;
width: 100px;
height: 100px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
} div::before {
content: "";
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
opacity: 0;
}

然后,在 hover 的时候,我们只需要将伪元素的透明度从 0 设置为 1 即可。

div:hover::before {
opacity: 1;
}

这样做的好处是,实际在进行的阴影变化,其实只是透明度的变化,而没有对阴影进行不断的重绘,有效的提升了阴影动画的流畅程度,让它看起来更加丝滑。

为什么对透明度 opacity 进行动画要比对 box-shadow 进行动画性能更好呢?可以看看这里这张表格,列举了不同属性变换对页面重排、重绘的影响:

very few CSS properties

最后,Demo 可以看看:

CodePen Demo -- 优化box-shadow动画

存在的问题,另外一种方案

原文中上述这个方案其实并不算太完美,因为最终的效果是两个阴影的叠加效果,可能会在整体的感觉上阴影颜色更深了一点。

所以需要对最终状态的阴影进行微调一下,削弱一点效果,尽量让两个阴影的叠加效果与单一一个阴影效果相近。

当然,我们可以再对上述方案进行优化,我们再使用一个 ::after 伪元素,::after 伪元素设置为初始状态且透明度为1,::before 伪元素设置为末尾状态且透明度为0:

div {
position: relative;
width: 100px;
height: 100px;
} div::before {
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
opacity: 0;
} div::after {
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
}

实际 hover 的时候,对两个伪元素进行一显一隐,这样最终的效果只有一个阴影效果,没有阴影的叠加,与直接对阴影进行过渡变化效果一致:

div:hover::before {
opacity: 1;
} div:hover::after {
opacity: 0;
}

CodePen Demo -- 优化box-shadow动画

最后

好了,本文到此结束,希望对你有帮助 :)

更多精彩 CSS 技术文章汇总在我的 Github -- iCSS ,持续更新,欢迎点个 star 订阅收藏。

最新文章

  1. ACM 中 矩阵数据的预处理 && 求子矩阵元素和问题
  2. HTML5- Canvas入门(四)
  3. TRIGGER_15.8.3BACKUP
  4. assign与weak区别(面试)
  5. overflow:hidden---清除浮动,隐藏溢出
  6. C语言基本数据类型
  7. WPF 应用程序使用 Multilingual App Toolkit
  8. php整理(二): 数组
  9. Python学习(二):函数入门
  10. net读取文件字节流要注意的小细节
  11. windows控件理论学习
  12. 4、原生jdbc链接数据库常用资源名
  13. unity打成aar上传到maven库的工具
  14. centos7.4 可远程可视化桌面安装
  15. Python 中的几种矩阵乘法 np.dot, np.multiply, *【转】
  16. JAVA读取控制台的输入【转】
  17. WebService使用介绍(一)
  18. Eavl整理
  19. Linux内核锁与中断处理
  20. nginx实现防盗链配置方法介绍

热门文章

  1. java中的逃逸分析
  2. Python必备收藏!Pycharm 常用快捷键思维导图!
  3. Spark开发常用参数
  4. python2.7过渡到python3.6时遇到的差异总结
  5. 数据分析--Matplotlib的基本使用
  6. 3D漫游的分类 3D Navigation Taxonomy
  7. 【集群监控】Docker上部署Prometheus+Alertmanager+Grafana实现集群监控
  8. 从零开始入门 K8s | 应用存储和持久化数据卷:存储快照与拓扑调度
  9. [Git] Git 使用记录
  10. MongoDB 学习笔记之 索引