今天寫代碼用antd-mobile的checkbox時候,想在內容文本後面添加一個icon,而且須要對這個icon綁定事件,發現綁定以後怎麼也點不中,調試發現原來被層層嵌套的dom元素蓋住了,確定是z-index在做祟。但是按照我以前對z-index的瞭解(自信滿滿)卻怎麼也不能把他由「被蓋住」改爲「蓋住別人」,在一通「盲改」代碼以後,終於「蓋住」其餘dom元素了。然而內心老是在想難道以前本身對z-index的認知有問題麼,抱着這樣的心態決定從新去學習,下面進入正文css
其實我想說大部分前端開發是不重視css的,也就致使了對css的不少屬性認知都是表面的,這其中z-index就是最典型的一個,下面列舉的錯誤認知還請你們對號入座:html
例以下面的例子:要比較div1-1-1 和 div2-1 是要看div1 和 div2 的比較結果呢前端
<div class="div1"> <div> <div class="div1-1-1" /> </div> </div> <div class="div2"> <div class="div2-1" /> </div>
若是以上三個你們都中槍了,不要緊,看完這篇文章你就永遠告別了,在遇到z-index的問題不再會「盲改,亂試」了web
層疊順序(stacking order)
層疊順序表示發生層疊時有着特定的垂直顯示順序(規則)。
即:網上這張很流行的規則
瀏覽器
關於這張圖有一些補充:
位於最下面的background/border特指層疊上下文元素的邊框和背景色。每個層疊順序規則僅適用當前層疊上下文元素的小世界
inline水平盒子指的是包括inline/inline-block/inline-table元素的層疊順序,他們都是同級別的
單純從層疊水平上看,實際上z-index:0和auto是能夠當作同樣的,可是在層疊上下文領域有着根本性的差別antd
層疊上下文的層疊水平要比普通元素高
層疊上下文能夠阻斷元素的混合模式
層疊上下文能夠嵌套,內部層疊上下文及其全部子元素均受制於外部的層疊上下文
每一個層疊上下文和兄弟元素獨立,也就是說,當進行層疊變化或者渲染的時候,只須要考慮後代元素
每一個層疊上下文是自成體系的,當元素髮生層疊的時候,整個元素被認爲是在父層疊上下文的層疊順序中dom
根元素 (HTML)
z-index 值不爲 "auto"的 絕對/相對定位(在firefox/ie瀏覽器下position: fixed也是能夠的)
一個 z-index 值不爲 "auto"的 flex 項目 (flex item),即:父元素 display: flex|inline-flex
opacity 屬性值小於 1 的元素(參考 the specification for opacity)
transform 屬性值不爲 "none"的元素
mix-blend-mode 屬性值不爲 "normal"的元素
filter值不爲「none」的元素
perspective值不爲「none」的元素
isolation 屬性被設置爲 "isolate"的元素
position: fixed
在 will-change 中指定了任意 CSS 屬性,即使你沒有直接指定這些屬性的值(參考這篇文章)
-webkit-overflow-scrolling 屬性被設置 "touch"的元素學習
層疊上下文與層疊順序flex
文章中屢次提到普通元素具有層疊上下文後層疊水平就會變高,那麼他究竟在層疊順序那個規則圖的哪一個位置呢
把目光向上鎖定,第二條列舉了12個能夠建立層疊上下文的方法,咱們把他分爲兩類:第二三條和其餘。
依賴z-index取值的:位置取決於z-index的值
不依賴z-index取值的:在圖中第二高的位置,即:z-index = auto 或者 0spa
用一個例子來講明:
<div class="container"> <div class="div1">111</div> <div class="div2">222</div> </div>
.container { width: 500px; height: 500px; background-color: #000; color: #fff; transform: scale(1); /* 給container建立層疊上下文 */ } .div1 { padding: 50px; background-color: aqua; z-index: 0; position: relative; /* 給div1建立層疊上下文,層疊水平依賴z-index的取值 */ } .div2 { padding: 50px; background-color: red; opacity: 0.8; /* 給div2建立層疊上下文,層疊水平依賴z-index的取值 */ /* margin-top: -40px; */ }
這個例子中一目瞭然,div1和div2的層疊水平同樣,都是在規則那張圖的第二高的位置,不過div2在div1的dom節點後面,因此div2要比div1的層疊水平高,咱們把margin-top的註釋去掉看下:
要想使得div1在上面只須要把div1的z-index改爲大於0的值就行了。
仍是上面的htl結構,接下來咱們再來看一個有意思的例子:
.container { width: 500px; height: 500px; background-color: #000; color: #fff; transform: scale(1); /* 給container建立層疊上下文 */ } .div1 { padding: 50px; background-color: aqua; opacity: 0.8; /* 給div1建立層疊上下文,層疊水平在z-index:0 */ } .div2 { padding: 50px; background-color: red; position: relative; margin-top: -40px; }
你們確定會說,div1明顯蓋過div2啊,但是咱們來看下實際狀況:
實際狀況下面的div2蓋過了div1,緣由是當html元素設置定位屬性的時候(absolute/relative),其z-index屬性自動生效變成
z-index: auto,因此這時候div1和div2的層疊水平是一致的,而div2在div1的dom節點後面,因此蓋過了div1(注意這裏div2並無變成層疊上下文元素,這是有本質區別的)
如今咱們在一塊兒看下文章開頭提到的幾個常見的錯誤認知:
文章到這裏就結束了,但願看完這篇文章的同窗能夠完全理解z-index。