天天看點

translate元素中的Position: fixed

最近寫奇葩的布局遇到了奇葩的問題,想給一個父元素加上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.

- 然後下面提了個issue

Is 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