CSS:你真的會用 z-index 嗎?

你真的會用 z-index 麼?

若是你的 css 裏面存在大量這樣的代碼:
    z-index:6六、66六、99九、9999
可能你還不太理解 z-index
複製代碼

HTML 元素是處於三維空間中

全部的盒模型元素都處於三維座標系中,除了咱們經常使用的橫座標和縱座標,盒模型元素還能夠沿着「z 軸」層疊擺放,當他們相互覆蓋時,z 軸順序就變得十分重要。css

但「z 軸」順序,不徹底由 z-index 決定,在層疊比較複雜的 HTML 元素上使用 z-index 時,結果可能讓人以爲困惑,甚至難以想象。這是由複雜的元素排布規則致使的。html

不含 z-index 元素如何堆疊?

當沒有元素包含z-index屬性時,元素按照以下順序堆疊(從底到頂順序):前端

  1. 根元素(<html>)的背景和邊界;
  2. 位於普通流中的後代「無定位塊級元素」,按它們在HTML中的出現順序堆疊;
  3. 後代中的「定位元素」,按它們在HTML中的出現順序堆疊;

注意:普通流中的「無定位塊級元素」始終先於「定位元素」渲染,並出如今「定位元素」下層,即使它們在HTML結構中出現的位置晚於定位元素也是如此。web

<!DOCTYPE html>
<html>
<head><style type="text/css">
  b {
    font-family: sans-serif;
  }

  div {
    padding: 10px;
    border: 1px dashed;
    text-align: center;
  }

  .static {
    position: static;
    height: 80px;
    background-color: #ffc;
    border-color: #996;
  }

  .absolute {
    position: absolute;
    width: 150px;
    height: 350px;
    background-color: #fdd;
    border-color: #900;
    opacity: 0.7;
  }

  .relative {
    position: relative;
    height: 80px;
    background-color: #cfc;
    border-color: #696;
    opacity: 0.7;
  }

  #abs1 {
    top: 10px;
    left: 10px;
  }

  #rel1 {
    top: 30px;
    margin: 0px 50px 0px 50px;
  }

  #rel2 {
    top: 15px;
    left: 20px;
    margin: 0px 50px 0px 50px;
  }

  #abs2 {
    top: 10px;
    right: 10px;
  }

  #sta1 {
    background-color: #ffc;
    margin: 0px 50px 0px 50px;
  }
</style></head>
<body>
  <div id="abs1" class="absolute">
    <b>DIV #1</b><br />position: absolute;</div>
  <div id="rel1" class="relative">
    <b>DIV #2</b><br />position: relative;</div>
  <div id="rel2" class="relative">
    <b>DIV #3</b><br />position: relative;</div>
  <div id="abs2" class="absolute">
    <b>DIV #4</b><br />position: absolute;</div>
  <div id="sta1" class="static">
    <b>DIV #5</b><br />position: static;</div>
</body></html>
複製代碼

float 如何影響堆疊?

對於浮動的塊元素來講,層疊順序變得有些不一樣。浮動塊元素被放置於非定位塊元素與定位塊元素之間:面試

  1. 根元素(<html>)的背景和邊界;
  2. 位於普通流中的後代「無定位塊級元素」,按它們在HTML中的出現順序堆疊;
  3. 浮動塊元素;<<<<
  4. 位於普通流中的後代「無定位行內元素」;
  5. 後代中的「定位元素」,按它們在HTML中的出現順序堆疊;

<!DOCTYPE html><html><head>
<meta charset="UTF-8">
<title>Stacking and float</title>
<style type="text/css">
  div {
    padding: 10px;
    text-align: center;
  }

  b {
    font-family: sans-serif;
  }

  #abs1 {
    position: absolute;
    width: 150px;
    height: 200px;
    top: 20px;
    right: 160px;
    border: 1px dashed #900;
    background-color: #fdd;
  }

  #sta1 {
    height: 100px;
    border: 1px dashed #996;
    background-color: #ffc;
    margin: 0px 10px 0px 10px;
    text-align: left;
  }

  #flo1 {
    margin: 0px 10px 0px 20px;
    float: left;
    width: 150px;
    height: 200px;
    border: 1px dashed #090;
    background-color: #cfc;
  }

  #flo2 {
    margin: 0px 20px 0px 10px;
    float: right;
    width: 150px;
    height: 200px;
    border: 1px dashed #090;
    background-color: #cfc;
  }

  #abs2 {
    position: absolute;
    width: 300px;
    height: 100px;
    top: 150px;
    left: 100px;
    border: 1px dashed #990;
    background-color: #fdd;
  }
</style></head>
<body>
  <div id="abs1">
    <b>DIV #1</b><br />position: absolute;</div>

  <div id="flo1">
    <b>DIV #2</b><br />float: left;</div>

  <div id="flo2">
    <b>DIV #3</b><br />float: right;</div>
  
  <br/>

  <div id="sta1">
    <b>DIV #4</b><br />no positioning</div>

  <div id="abs2">
    <b>DIV #5</b><br />position: absolute;</div>
</body>
</html>
複製代碼

z-index 如何影響堆疊?

z-index 屬性指定了一個具備定位屬性的元素及其子代元素的 z-order。 當元素之間重疊的時候,z-order 決定哪個元素覆蓋在其他元素的上方顯示。 一般來講 z-index 較大的元素會覆蓋較小的一個。bash

對於一個已經定位的元素(即position屬性值不是static的元素),z-index 屬性指定:ide

  1. 元素在當前堆疊上下文中的堆疊層級。
  2. 元素是否建立一個新的本地堆疊上下文。

<!DOCTYPE html>
<html>
<head><style type="text/css">

div {
   opacity: 0.7;
   font: 12px Arial;
}

span.bold { font-weight: bold; }

#normdiv {
   z-index: 8;
   height: 70px;
   border: 1px dashed #999966;
   background-color: #ffffcc;
   margin: 0px 50px 0px 50px;
   text-align: center;
}

#reldiv1 {
   z-index: 3;
   height: 100px;
   position: relative;
   top: 30px;
   border: 1px dashed #669966;
   background-color: #ccffcc;
   margin: 0px 50px 0px 50px;
   text-align: center;
}

#reldiv2 {
   z-index: 2;
   height: 100px;
   position: relative;
   top: 15px;
   left: 20px;
   border: 1px dashed #669966;
   background-color: #ccffcc;
   margin: 0px 50px 0px 50px;
   text-align: center;
}

#absdiv1 {
   z-index: 5;
   position: absolute;
   width: 150px;
   height: 350px;
   top: 10px;
   left: 10px;
   border: 1px dashed #990000;
   background-color: #ffdddd;
   text-align: center;
}

#absdiv2 {
   z-index: 1;
   position: absolute;
   width: 150px;
   height: 350px;
   top: 10px;
   right: 10px;
   border: 1px dashed #990000;
   background-color: #ffdddd;
   text-align: center;
}
</style></head>

<body>

<br /><br />

<div id="absdiv1">
   <br /><span class="bold">DIV #1</span>
   <br />position: absolute;
   <br />z-index: 5;
</div>

<div id="reldiv1">
   <br /><span class="bold">DIV #2</span>
   <br />position: relative;
   <br />z-index: 3;
</div>

<div id="reldiv2">
   <br /><span class="bold">DIV #3</span>
   <br />position: relative;
   <br />z-index: 2;
</div>

<div id="absdiv2">
   <br /><span class="bold">DIV #4</span>
   <br />position: absolute;
   <br />z-index: 1;
</div>

<div id="normdiv">
   <br /><span class="bold">DIV #5</span>
   <br />no positioning
   <br />z-index: 8;
</div>

</body></html>
複製代碼

堆疊上下文(Stacking Context)

什麼是堆疊上下文?

層疊上下文(Stacking Context)是HTML元素的三維概念,這些HTML元素在一條假想的相對於面向(電腦屏幕的)視窗或者網頁的用戶的z軸上延伸,HTML元素依據其自身屬性按照優先級順序佔用層疊上下文的空間。學習

在層疊上下文中,其子元素的 z-index 值只在父級層疊上下文中有意義。子級層疊上下文被自動視爲父級層疊上下文的一個獨立單元。flex

  • 層疊上下文能夠包含在其餘層疊上下文中,而且一塊兒建立一個有層級的層疊上下文。
  • 每一個層疊上下文徹底獨立於它的兄弟元素:當處理層疊時只考慮子元素。
  • 每一個層疊上下文是自包含的:當元素的內容發生層疊後,整個該元素將會 在父層疊上下文中 按順序進行層疊。

如何造成堆疊上下文?

  • 根元素 (HTML)
  • 定位元素(relative、absolute),而且 z-index 不爲 auto;
  • opacity 小於 1 時;
  • transform 不爲 none 時;
  • z-index 不爲 auto 的 flex-item;

注:層疊上下文的層級是 HTML 元素層級的一個層級,由於只有某些元素纔會建立層疊上下文。能夠這樣說,沒有建立本身的層疊上下文的元素 將被父層疊上下文包含。 ui

<!DOCTYPE html>
<html>
<head><style type="text/css">
* {
    margin: 0;
}
html {
    padding: 20px;
    font: 12px/20px Arial, sans-serif;
}
div {
    opacity: 0.7;
    position: relative;
}
h1 {
    font: inherit;
    font-weight: bold;
}
#div1,
#div2 {
    border: 1px dashed #696;
    padding: 10px;
    background-color: #cfc;
}
#div1 {
    z-index: 5;
    margin-bottom: 190px;
}
#div2 {
    z-index: 2;
}
#div3 {
    z-index: 4;
    opacity: 1;
    position: absolute;
    top: 40px;
    left: 180px;
    width: 330px;
    border: 1px dashed #900;
    background-color: #fdd;
    padding: 40px 20px 20px;
}
#div4,
#div5 {
    border: 1px dashed #996;
    background-color: #ffc;
}
#div4 {
    z-index: 6;
    margin-bottom: 15px;
    padding: 25px 10px 5px;
}
#div5 {
    z-index: 1;
    margin-top: 15px;
    padding: 5px 10px;
}
#div6 {
    z-index: 3;
    position: absolute;
    top: 20px;
    left: 180px;
    width: 150px;
    height: 125px;
    border: 1px dashed #009;
    padding-top: 125px;
    background-color: #ddf;
    text-align: center;
}
</style></head>

<body>

<br /><br />

<div id="div1">
      <h1>Division Element #1</h1>
      <code>position: relative;<br/>
      z-index: 5;
    </div>

    <div id="div2">
      <h1>Division Element #2</h1>
      <code>position: relative;<br/>
      z-index: 2;
    </div>

    <div id="div3">
      
      <div id="div4">
        <h1>Division Element #4</h1>
        <code>position: relative;<br/>
        z-index: 6;
      </div>

      <h1>Division Element #3</h1>
      <code>position: absolute;<br/>
      z-index: 4;

      <div id="div5">
        <h1>Division Element #5</h1>
        <code>position: relative;<br/>
        z-index: 1;
      </div>

      <div id="div6">
        <h1>Division Element #6</h1>
        <code>position: absolute;<br/>
        z-index: 3;
      </div>
    </div>

</body></html>
複製代碼

堆疊上下文如何影響堆疊?

  1. 元素的 background 和 borders;
  2. 擁有負堆疊層級(negative stack levels)的子層疊上下文(child stacking contexts)
  3. 在文檔流中的(in-flow),非行內級的(non-inline-level),非定位(non-positioned)的後代元素
  4. 非定位的浮動元素
  5. 在文檔流中的(in-flow),行內級的(inline-level),非定位(non-positioned)的後代元素,包括行內塊級元素(inline blocks)和行內表格元素(inline tables)
  6. 堆疊層級爲 0 的子堆疊上下文(child stacking contexts)和堆疊層級爲 0 的定位的後代元素
  7. 堆疊層級爲正的子堆疊上下文

上述關於層次的繪製規則遞歸地適用於任何層疊上下文。

<!DOCTYPE html>
<html>
<head><style type="text/css">

div { font: 12px Arial; }

span.bold { font-weight: bold; }

div.lev1 {
   width: 250px;
   height: 70px;
   position: relative;
   border: 2px outset #669966;
   background-color: #ccffcc;
   padding-left: 5px;
}

#container1 {
   z-index: 1;
   position: absolute;
   top: 30px;
   left: 75px;
}

div.lev2 {
   opacity: 0.9;
   width: 200px;
   height: 60px;
   position: relative;
   border: 2px outset #990000;
   background-color: #ffdddd;
   padding-left: 5px;
}

#container2 {
   z-index: 1;
   position: absolute;
   top: 20px;
   left: 110px;
}

div.lev3 {
   z-index: 10;
   width: 100px;
   position: relative;
   border: 2px outset #000099;
   background-color: #ddddff;
   padding-left: 5px;
}
</style></head>

<body>

<br />

<div class="lev1">
<span class="bold">LEVEL #1</span>
   <div id="container1">
      <div class="lev2">
      <br/><span class="bold">LEVEL #2</span>
      <br/>z-index: 1;
         <div id="container2">
            <div class="lev3"><span class="bold">LEVEL #3</span></div>
            <div class="lev3"><span class="bold">LEVEL #3</span></div>
            <div class="lev3"><span class="bold">LEVEL #3</span></div>
            <div class="lev3"><span class="bold">LEVEL #3</span></div>
            <div class="lev3"><span class="bold">LEVEL #3</span></div>
            <div class="lev3"><span class="bold">LEVEL #3</span></div>
            <div class="lev3"><span class="bold">LEVEL #3</span></div>
            <div class="lev3"><span class="bold">LEVEL #3</span></div>
            <div class="lev3"><span class="bold">LEVEL #3</span></div>
            <div class="lev3"><span class="bold">LEVEL #3</span></div>
            <div class="lev3"><span class="bold">LEVEL #3</span></div>
         </div>
      </div>
      
      <div class="lev2">
      <br/><span class="bold">LEVEL #2</span>
      <br/>z-index: 1;
      </div>
   </div>
</div>

<div class="lev1">
<span class="bold">LEVEL #1</span>
</div>

<div class="lev1">
<span class="bold">LEVEL #1</span>
</div>

<div class="lev1">
<span class="bold">LEVEL #1</span>
</div>

</body></html>
複製代碼

最佳實踐(不犯二準則)

對於非浮層元素,避免設置 z-index 值,z-index 值沒有任何道理須要超過2,緣由是:

  1. 定位元素一旦設置了 z-index 值,就從普通定位元素變成了層疊上下文元素,相互間的層疊順序就發生了根本的變化,很容易出現設置了巨大的 z-index 值也沒法覆蓋其餘元素的問題。
  2. 避免 z-index 「一山比一山高」的樣式混亂問題。此問題多發生在多人協做以及後期維護的時候。例如,A小圖標定位,習慣性寫了個 z-index: 9;B一看,本身原來的實現被覆蓋了,立馬寫了個 z-index: 99;結果比彈框組件層級還高,立馬彈框組件來一個 z-index: 99999……顯然,最後項目的 z-index 層級管理就是一團糟。

CSS世界

考覈(荔枝FM面試題)

寫出6個div元素的堆疊順序,最上面的在第一個位置,例如: .one .two .three .four .five .six(z-index);

html:

<div class="one">
    <div class="two"></div>
    <div class="three"></div>
</div>
<div class="four">
    <div class="five"></div>
    <div class="six"></div>
</div>
複製代碼

css:

.one {
    position: relative;
    z-index: 2;
    .two {
        z-index: 6;
    }
    .three {
        position: absolute;
        z-index: 5;
    }
}
.four {
    position: absolute;
    z-index: 1;
    .five {}
    .six {
        position: absolute;
        top: 0;
        left: 0;
        z-index: -1;
    }
}
複製代碼

答案:

.three .two .one .five .six .four
複製代碼

參考:

《CSS世界》

Understanding CSS z-index: developer.mozilla.org/zh-CN/docs/…

CSS2.2,Layered presentation: www.w3.org/TR/CSS22/vi…

z-index: developer.mozilla.org/en-US/docs/…

Elaborate description of Stacking Contexts: www.w3.org/TR/CSS22/zi…

How z-index Works: bitsofco.de/how-z-index…

What No One Told You About Z-Index: philipwalton.com/articles/wh…

What You May Not Know About the Z-Index Property: webdesign.tutsplus.com/articles/wh…

Z-Index And The CSS Stack: Which Element Displays First?: vanseodesign.com/css/css-sta…

社區以及公衆號發佈的文章,100%保證是咱們的原創文章,若是有錯誤,歡迎你們指正。

文章首發在WebJ2EE公衆號上,歡迎你們關注一波,讓咱們你們一塊兒學前端~~~

再來一波號外,咱們成立WebJ2EE公衆號前端吹水羣,你們不論是看文章仍是在工做中前端方面有任何問題,咱們均可以在羣內互相探討,但願可以用咱們的經驗幫更多的小夥伴解決工做和學習上的困惑,歡迎加入。

相關文章
相關標籤/搜索