最近写奇葩的布局遇到了奇葩的问题,想给一个父元素加上translate3d来实现GPU加速,发现加上tranlate3d之后,fixed定位的自元素不是相对于viewport了,二是相对于有translate3d的父元素。
查了查fixed的定义,按照标准定位确实是相对于viewport
- https://www.w3.org/TR/css-position-3/#fixed-pos
Fixed positioning is similar to absolute positioning. The only difference is that for a fixed positioned box, the containing block is established by the viewport.
于是又查了查fixed和translate,找到了答案
- transfomr会生一个层叠上下文和一个包含块(containing block),这个东东会成为fixed定位的子元素的包含块。
- https://www.w3.org/TR/css-transforms-1/#transform-rendering
For elements whose layout is governed by the CSS box model, any value other than none for the transform results in the creation of both a stacking context and a containing block. The object acts as a containing block for fixed positioned descendants.
- 然后下面提了个issueIs this effect on position: fixed necessary? If so, need to go into
more detail here about why fixed positioned objects should do this,
i.e., that it’s much harder to implement otherwise. See Bug 16328.
最后曲线救国,用will-change去实现新图层加速,但是使用will-change也要注意
用 3D 变换开启硬件加速,这个方法其实是个 hack 手段,每个 hack 的背后都有各种惊心动魄的坑。will-change 则是一个更加符合人类逻辑的方法。这个属性意在告诉浏览器,什么元素将发生什么变化,这样浏览器可以提前做好优化准备,就像起跳前的助跑一样。
文档建议是通过 js 来控制 will-change,如果把 will-change 常驻在某个元素上,比如在 css 文件中有一行 .ele { will-change:transform; },那么浏览器会一直处于“警备状态”,也就是说浏览器始终会分配资源给这个元素。所以,最好是动态地控制这个属性,保证浏览器资源不会被浪费,特别是在 CPU GPU 处理能力和内存吃紧的移动设备上。当动画结束的时候,及时将 will-change 属性值变回 auto,释放资源。
上文说到了当动画结束时,will-change 的值要及时被更新为 auto,这个通过 js 可以掐准时间。但现在,要抛出一个早该问出的问题了:结束时要改变,开始时也需要变呀,那什么时候添加这个属性呢?可不能动画执行了一半,才加上这个属性。要在动画发生之前,给浏览器足够的反应时间才行。这篇文章中的作者提到了一个场景,如果一个元素在 hover 时如果会出现动画,那么就要在它的父级元素 hover 时,就给这个元素加上 will-change;
PS,关于启动GPU加速可以戳http://blog.csdn.net/u010552788/article/details/52186108,虽然写的很少搓搓的,可以继续戳参考文献 233333