完全理解z-index,看完仍是隻會無厘頭的設置9999你打我~~~~

今天寫代碼用antd-mobile的checkbox時候,想在內容文本後面添加一個icon,而且須要對這個icon綁定事件,發現綁定以後怎麼也點不中,調試發現原來被層層嵌套的dom元素蓋住了,確定是z-index在做祟。但是按照我以前對z-index的瞭解(自信滿滿)卻怎麼也不能把他由「被蓋住」改爲「蓋住別人」,在一通「盲改」代碼以後,終於「蓋住」其餘dom元素了。然而內心老是在想難道以前本身對z-index的認知有問題麼,抱着這樣的心態決定從新去學習,下面進入正文css

90%的前端開發對z-index的認知

其實我想說大部分前端開發是不重視css的,也就致使了對css的不少屬性認知都是表面的,這其中z-index就是最典型的一個,下面列舉的錯誤認知還請你們對號入座:html

  • z-index值越大越「靠近咱們」 -- 最初級的認知
  • 要搭配position: absolute | relative | fixed 使用纔有用呢 -- 稍微進階一些的認知
  • 比較兩個兄弟節點誰更「靠近咱們」,要看他們的同級父元素的比較呢。-- 多是大部分前端的終極認知了

例以下面的例子:要比較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

三個概念 -- 層疊上下文、層疊水平、層疊順序

  1. 層疊上下文(stacking context)
    看到上下文這個關鍵詞,我想你們應該會有一點概念,沒錯就是context。和大家認識的那個BFC、IFC裏面的上下文是一個意思,其實我想說css世界裏面看到context或者XXX上下文其實都是同一個意思,徹底能夠理解爲自成一派,在本身的小世界裏面隨便折騰,不受其餘的context影響。固然,這個context是能夠被其餘context包含同時也能夠包含其餘context
  2. 層疊水平(stacking level)
    層疊水平決定了在同一個層疊上下文中元素在Z軸上的顯示順序。
    頁面中的全部元素(普通元素和層疊上下文元素)都有層疊水平。然而對普通元素的層疊水平探討只侷限在層疊上下文元素中。
    注:你們千萬不要把層疊水平和z-index混爲一談,儘管某些狀況下z-index確實能夠影響層疊水平,可是也只侷限於具備層疊上下文的元素,而層疊水平是全部元素都存在的
  3. 層疊順序(stacking order)
    層疊順序表示發生層疊時有着特定的垂直顯示順序(規則)。
    即:網上這張很流行的規則
    clipboard.png瀏覽器

    關於這張圖有一些補充:
    位於最下面的background/border特指層疊上下文元素的邊框和背景色。每個層疊順序規則僅適用當前層疊上下文元素的小世界
    inline水平盒子指的是包括inline/inline-block/inline-table元素的層疊順序,他們都是同級別的
    單純從層疊水平上看,實際上z-index:0和auto是能夠當作同樣的,可是在層疊上下文領域有着根本性的差別antd

深刻了解層疊上下文

  1. 特性

    層疊上下文的層疊水平要比普通元素高
    層疊上下文能夠阻斷元素的混合模式
    層疊上下文能夠嵌套,內部層疊上下文及其全部子元素均受制於外部的層疊上下文
    每一個層疊上下文和兄弟元素獨立,也就是說,當進行層疊變化或者渲染的時候,只須要考慮後代元素
    每一個層疊上下文是自成體系的,當元素髮生層疊的時候,整個元素被認爲是在父層疊上下文的層疊順序中dom

  2. 如何建立

    根元素 (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"的元素學習

  3. 層疊上下文與層疊順序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的註釋去掉看下:

    clipboard.png
    要想使得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啊,但是咱們來看下實際狀況:

    clipboard.png

    實際狀況下面的div2蓋過了div1,緣由是當html元素設置定位屬性的時候(absolute/relative),其z-index屬性自動生效變成
    z-index: auto,因此這時候div1和div2的層疊水平是一致的,而div2在div1的dom節點後面,因此蓋過了div1(注意這裏div2並無變成層疊上下文元素,這是有本質區別的

常見錯誤認知解析

如今咱們在一塊兒看下文章開頭提到的幾個常見的錯誤認知:

  • z-index值越大越「靠近咱們」 -- 並不必定,首先要成爲層疊上下文。或者若是比較的元素的父元素也是層疊上下文,那就徹底取決於父元素了
  • 要搭配position: absolute | relative | fixed 使用纔有用呢 -- 對了一部分,還有其餘的條件也可使元素稱爲層疊上下文元素
  • 比較兩個兄弟節點誰更「靠近咱們」,要看他們的同級父元素的比較呢。-- 若是同級父元素不是層疊上下文元素就不須要看「父元素的眼色」了

文章到這裏就結束了,但願看完這篇文章的同窗能夠完全理解z-index。

相關文章
相關標籤/搜索