transform
想必你們都很熟悉,能夠經過其轉換(translate)、旋轉(rotate)、縮放(scale)、傾斜(skew)等屬性來對元素進行變換,不過這篇文章想探討的不是這些內容,而是 transform
對元素佈局、頁面渲染方面的影響。例如,你知道它會影響 fixed
元素的位置嗎?你有想過它會改變元素的層疊順序嗎?css
首先咱們來看一個例子(代碼在這裏):下面示例中的 fixed 元素設置的是 top: -50px
,按理說咱們應該是看不見它的,由於它會相對根元素定位到頁面上方的外部。然而事實狠狠打了咱們的臉,它是可見的!這是爲何呢?html
關鍵就在於這個 fixed
元素被擁有 transform
的屬性的父 div 包裹着,因此它會相對於這個 transform
的父元素定位,而不是咱們覺得的根元素定位,又因爲父元素有 margin-top: 50px
的值,因此二者相抵消(-50px + 50px = 0),最終致使該元素位於頁面起始處。css3
至於爲何會這樣,就須要從 W3C 規範中去尋找緣由了。在 W3C - transform rendering 中,我找到了這樣一段解釋:For elements whose layout is governed by the CSS box model, any value other than none
for the transform also causes the element to become a containing block, and the object acts as a containing block for fixed positioned descendants,也就是說 transform 值不爲 none
的元素會建立一個 containing block(做者注:容器塊,盒元素定位和大小通常參考容器塊進行計算),而後該元素的 fixed
子元素會相對該元素進行定位。web
緣由搞明白了,那麼爲何 W3C 委員會會這樣設計呢?依我愚見,能夠從兩個方面來思考:segmentfault
fixed 元素
相對根元素進行絕對定位,咱們每每會把它做爲根元素的第一級子元素,從而也就不會存在它被 transform 父元素
包裹的狀況了。fixed 元素
放在 transform 父元素
下呢?在我看來,只有咱們但願它跟隨父元素一塊兒變形時纔會這樣作,要否則爲何不把它放在根元素下呢?一樣的,咱們先來看一個例子(代碼在這裏):下面示例中第一行爲啥都沒加的狀況下,讓第二個元素(藍色塊)經過 margin-left: -40px
向左偏移了 40px,按照後來居上的層疊規則,它會蓋住第一個元素(黃色塊)的一部分。第二行給第一個元素(黃色塊)加上了 transform: scale(1)
後一切就變了,它蓋住了第二個元素(藍色塊),後來居上的規則貌似不起做用了,這是爲何呢?ide
一樣的,仍是嘗試從 W3C 規範中去尋找緣由。在 W3C - 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 a stacking context,也就是說 transform 值不爲 none
的元素會建立一個 stacking context
(層疊上下文)。層疊上下文,這是什麼鬼?好像只聽過塊級格式化上下文(BFC)。wordpress
簡單說來,層疊上下文與元素在 z 軸上的展現順序相關,並且層疊上下文元素的層疊水平要比普通元素高,結合上面的例子來講就是:佈局
none
,因此升級爲層疊上下文元素,於是它的層疊水平比黃色塊(普通元素)高。層疊上下文的內容值得深刻地具體探究,這裏推薦兩個不錯內容,一個是 MDN - 層疊上下文,另一個則是 張鑫旭 - 深刻理解CSS中的層疊上下文和層疊順序。ui
當使用 CSS 遇到奇奇怪怪問題的時候,咱們既能夠在 Google 或者 StackOverflow 上尋找答案,也不要忘了 W3C 的存在。有時真相其實早已靜靜地躺在標準當中,只要咱們肯於尋找、善於尋找,定能找到 ^_^.net