DOM層級順序與z-index

前言

DOM層級順序,大概來講就是DOM節點在z軸方向(垂直於屏幕向外的方向)的顯示優先級。爲了調整DOM層級順序,咱們想到的每每就是用CSS的z-index屬性來控制。雖然看着很簡單,可是有時在使用時,咱們有時也許會碰到一些一些奇奇怪怪的問題:html

  • 爲何有時候將z-index設成很大的值(好比9999),節點依然不能顯示在最前面?
  • z-index屬性設爲0和不設置z-index屬性有什麼區別?
  • float元素和定位元素誰顯示的優先級更高?

其實看似簡單的層級順序它本身的一套規則,理解這些規則能夠幫助咱們在開發中少踩坑。web

規則

1. 順序規則

在不設置position屬性(或設置成static)的狀況下,文檔流後面的DOM節點會覆蓋前面的DOM節點。瀏覽器

<div id="a">A</div>
<div id="b">B</div>

clipboard.png

PS:怎麼樣來讓文檔流中的節點疊在一塊兒呢?好比咱們能夠設置DOM的margin-top爲負數,這樣就讓兩個節點疊在起一塊兒了。不過爲了簡化說明,並無把這些寫出來。下同。spa

2.定位規則

定位節點(position屬性設置爲relative,absolute或fixed的節點)會覆蓋非定位節點(不設置position屬性或position屬性設爲static的節點)3d

<div id="a" style="position: relative">A</div>
<div id="b">B</div>

clipboard.png

根據順序規則和定位規則, 咱們能夠作出更加複雜的結構。A和 B 都設爲非定位節點,A 的子節點 A-1 設定定位節點。code

<div id="a">
    <div id="a-1" style="position: relative">A</div>
</div>
<div id="b">B</div>

clipboard.png

3. 參與規則

z-index屬性僅對定位節點生效。orm

有三個DOM節點,其定位爲static。可是A的z-index最大,可是依舊是在最底部,C的z-index最小,而在最頂部,所以可知z-index並未生效,此時爲順序規則在生效。htm

<div id="a" style="z-index: 2">A</div>
<div id="b" style="z-index: 1">B</div>
<div id="b" style="z-index: 0">B</div>

clipboard.png

咱們將B和C的position設置爲relative以後,順序發生了變化。根據參與者規則和定位規則,A不是定位節點,因此即便z-index最大,仍是在最底部。而根據參與規則和默認值規則(下一節介紹),B和C都是定位節點,且B的z-index要大於C,因此B在最頂部。blog

<div id="a" style="z-index: 2">A</div>
<div id="b" style="position: relative; z-index: 1">B</div>
<div id="b" style="position: relative; z-index: 0">B</div>

clipboard.png

4. 默認值規則

  • 對於全部的定位節點,z-index值大的節點會覆蓋z-index值小的節點。
  • z-index設爲0和沒有設置z-index的節點在同一層級內沒有高低之分。在IE6和7種,z-index的默認值爲0,其餘瀏覽器中默認值爲auto。
<div id="a" style="position: relative; z-index: 1">A</div>
<div id="b" style="position: relative; z-index: 0">B</div>
<div id="c" style="position: relative">C</div>
<div id="d" style="position: relative; z-index: 0">D</div>

clipboard.png

5. 從父規則

兩個節點A和B都是定位節點,若是節點A的z-index值比節點B的大,那麼節點A的子元素都會覆蓋在節點B以及節點B的子節點上。ip

<div id="a" style="position: relative; z-index: 1">
    <div id="a-1">A-1</div>
</div>
<div id="b" style="position: relative; z-index: 0">
    <div id="b-1">B-1</div>
</div>

clipboard.png

若是定位節點A和B的z-index值同樣大,那麼根據順序規則,B會覆蓋A,那麼即便A的子節點的z-index比B的子節點大,B的子節點仍是會覆蓋A的子節點。(這就是爲何即便咱們把A-1的z-index設置得很大,依然沒法蓋住B節點的緣由)。

<div id="a" style="position: relative; z-index: 0">
    <div id="a-1" style="position: relative; z-index: 2">A-1</div>
</div>
<div id="b" style="position: relative; z-index: 0">
    <div id="b-1" style="position: relative; z-index: 1">B-1</div>
</div>

clipboard.png

6. 層級樹規則

定位節點,且z-index有整數值的(不包括z-index:auto),會被放置到一個與DOM節點不同的層級樹裏。

在下面的DOM節點中,A和B是兄弟節點,可是在層級樹種,A和B-1纔是兄弟節點(由於他們都是Root下的第一層含有整數z-index的定位節點),因此A在B和B-1之上。雖然A-1的z-index比B-1的小,可是根據從父規則,A-1也在B-1之上。

<div id="a" style="position: relative; z-index: 2">
    <div id="a-1" style="position: relative; z-index: 0">A-1</div>
</div>
<div id="b">
    <div id="b-1" style="position: relative; z-index: 1">B-1</div>
</div>

clipboard.png
clipboard.png

下面這個更復雜的層級樹,聰明的你能看明白爲何節點層級是這樣的了嗎?

<div id="a" style="position: relative">
    <div id="a-1" style="position: relative; z-index: 100">A-1</div>
</div>
<div id="b">
    <div id="b-1" style="position: relative">
        <div id="b-1-1" style="position: relative; z-index: 10">B-1-1</div>
    </div>
</div>
<div id="c" style="position: relative">
    <div id="c-1">
        <div id="c-1-1">
            <div id="c-1-1-1" style="position: relative; z-index: 1">C-1-1-1</div>
        </div>
    </div>
</div>

clipboard.png

層疊上下文

介紹了這麼多規則,是在是很差理解,又很難記。其實,要理解這些規則,咱們只須要理解一個概念就好了,它就是層疊上下文。

概念

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

特性

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

產生的條件

知足一下其中一個條件,便可產生一個層疊上下文:

  • 根元素 (HTML),
  • z-index 值不爲 "auto"的 絕對/相對定位,
  • position: fixed
  • opacity 屬性值小於 1 的元素
  • transform 屬性值不爲 "none"的元素
  • filter值不爲「none」的元素
  • -webkit-overflow-scrolling 屬性被設置 "touch"的元素

附錄:層疊的順序表

位置 描述 CSS
1(底部) 包含該層疊上下文的父元素
2 負堆疊順序的子元素 z-index: <negative integer>; position: relative (or absolute or fixed)
3 文檔流中,非內聯,非定位子元素 display: /* not inline */; position: static
4 非定位浮動子元素 float: left (or right); position: static
5 內聯流,非定位子元素 display: inline; position: static
6 堆疊順序爲0的子元素 z-index: auto (or 0); position: position: relative(or absolute or fixed)
7(頂部) 堆疊順序爲正的子元素 z-index: <positive integer>; position: relative(or absolute or fixed)
相關文章
相關標籤/搜索