浏览器启用NPAPI后页面CSS3动画的影响
问题描述:
产生条件:
在360安全浏览器/360极速浏览器(npapi插件开启)
CSS3动画及flash 共存
上述条件同时符合的场景下,在某个flash播放的时候,触发任意一个带有CSS3动画的元素,会发现flash消失,待CSS3动画播放完毕之后重新出现,如果页面比较复杂时会发现其它文本元素也会有闪动现象。(此时需要的字体饱和度(hsla中的s)较高,这样肉眼能够清晰的看到字体闪动。)
环境准备:
1,打开360安全浏览器【其它主流浏览器非NPAPI】
2. 先看下是否use npapi
方法: 在地址栏输入 se://plugins 如图查看是否开启
场景带入:
感谢文章CSS3硬件加速,硬件加速的方式,会把需要渲染的元素放到特定的复合层(composited layer)中,如果你想查看你的页面是否使用了2D或者3D加速,可以用下列方式去查看。
在控制台可以这样开启:【我以360安全浏览器为例】
勾选Show composited layer borders以后,就能看到有动画3d/2d变换的元素会被一个黄色的边框圈起来,表示放到了一个新的 "复合层(composited layer)" 中渲染,大概长这个样子:
蓝色的细线是浏览器渲染时候的瓦片,浏览器绘制页面的时候只会绘制可视区域一定范围内的瓦片,以节省性能开销,而黄色的边框框起来的,就代表了这个元素被放到特殊的复合层中渲染,跟主文档不在一个层中,但其实我只有其中的几处使用了2D动画,但显然很多并不会涉及的容器也被黄色的边框框了起来,经过排查发现,是因为CSS3动画【这儿要说一下动画包括 transform 和 animation, 不论是@keyframes 还是简单的 translate rotate ... 】导致之后所有绝对相对定位的元素都被放到复合层中渲染。
查了一些 资料:
层创建标准什么情况下能使元素获得自己的层?满足以下任意情况便会创建层:
3D 或透视变换(perspective transform) CSS 属性
使用加速视频解码的 元素
拥有 3D (WebGL) 上下文或加速的 2D 上下文的 元素
混合插件(如 Flash)
对自己的 opacity 做 CSS 动画或使用一个动画 webkit 变换的元素
拥有加速 CSS 过滤器的元素
元素有一个包含复合层的后代节点(换句话说,就是一个元素拥有一个子元素,该子元素在自己的层里)
元素有一个 z-index 较低且包含一个复合层的兄弟元素(换句话说就是该元素在复合层上面渲染)
最后一条,原文是:
Element has a sibling with a lower z-index which has a compositing layer (in other words the it’s rendered on top of a composited layer)
我回过头看了下我的页面,非常符合以上的条件,所以很容易被创建了复合层,导致怀疑 CSS3 3D加速的某些属性影响了页面中的内容的错觉 直至到后期flash动画与CSS3动画同时存在的场景里的时候 才得以解决。
解决方法:
1. 如果不存在flash,只有CSS3动画,影响到了页面其它例如字体抖动的情况下:
需要给动画元素加 position:relative和 z-index: 1,这种做法的原理是人为提升动画元素的z-index,让浏览器知道这个元素的层排序,就不会把其他z-index比它高的元素也弄到复合层中了;
2. 如果flash和CSS3动画并存,影响到了页面其它例如字体抖动的情况或者CSS3动画影响到了正在播放的flash的时候 :
需要动画元素加 position:relative和 z-index: 1,注意 一定要动画元素的z-index高于flash的z-index;
注:flash在制作的时候如果加了滤镜效果,在360安全浏览器【npapi】下,会有黑底出现,极其影响视觉感受。