CSS理解之z-index

1.z-index基礎

z-index屬性指定了元素及其子元素的[z順序],而[z順序]可以決定
當元素發生覆蓋的時候,哪個元素在上面。通常一個較大z-index值的元素會覆蓋較低的那一個。

z-index支持的屬性值:

1. z-index:auto;默認值,如果不對z-index設置,默認為auto;
2. z-index:<integer>;整數值,z-index:1,z-index:2等
3. z-index:inherit;繼承

z-index基本特性:

1. 支持負值;
2. 支持CSS3  animation動畫;
3. 在CSS2.1時代,不考慮CSS3,z-index要起作用需要和定位元素配合使用,只有定位元素(position:relative/absolute/fix/sticky)設置z-index才有作用(CSS3中有例外);

2. z-index與定位元素

如果定位元素發生了覆蓋,且沒有嵌套(不是一個定位元素里面嵌套著另一個定位元素),誰在上面遵守下面兩個準則:

1. 后來居上的準則,后面的覆蓋前面的;
2. z-index哪個大,哪個上;

demo 1:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
        .div1 img{
            position: absolute;
        }
        .div2 img{
            position: relative;
            margin-left: 100px;
        }
    </style>
</head>
<body>
    <div class="div1">
        ![](a.jpg)
    </div>
    <div class="div2">
        ![](b.jpg)
    </div>
</body>
</html>
Paste_Image.png

后面的定位元素覆蓋前面的定位元素在上面渲染。

demo 2:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
        .div1 img{
            position: absolute;
            z-index:2;
        }
        .div2 img{
            position: relative;
            z-index:1;
            margin-left: 100px;
        }
    </style>
</head>
<body>
    <div class="div1">
        ![](a.jpg)
    </div>
    <div class="div2">
        ![](b.jpg)
    </div>
</body>
</html>
Paste_Image.png

z-index值大的在上面覆蓋z-index值小的

另一種情況:定位元素z-index發生了嵌套,誰在上面遵循如下原則:

  1. 祖先優先原則;
    demo :
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
        .div1 img{
            position: absolute;
            z-index:3;
        }
        .div2 img{
            position: relative;
            z-index:-1;
            margin-left: 100px;
        }
    </style>
</head>
<body>
    <div class="div1" style="position: relative;z-index: 1;">
        ![](a.jpg)
    </div>
    <div class="div2" style="position: relative;z-index: 3;">
        ![](b.jpg)
    </div>
</body>
</html>
Paste_Image.png

可以看到嵌套了的z-index定位元素,盡管前面的子元素的z-index值大,還是后面的圖片覆蓋了前面的,這里就遵循了祖先優先原則。

前提:祖先的z-index值是數值不是auto

demo :

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
        .div1 img{
            position: absolute;
            z-index:2;
        }
        .div2 img{
            position: relative;
            z-index:1;
            margin-left: 100px;
        }
    </style>
</head>
<body>
    <div class="div1" style="position: relative;z-index: auto;">
        ![](a.jpg)
    </div>
    <div class="div2" style="position: relative;z-index:1;">
        ![](b.jpg)
    </div>
</body>
</html>
Paste_Image.png

當第一個圖片元素的祖先元素z-index值為auto時,祖先優先原則就會失效,z-index:auto可以看成是z-index:0,盡管第二個圖片元素的祖先元素z-index值比0大,但還是第一個圖片覆蓋第二個圖片。
CSS2.1:(z-index:auto時)當前層疊上下文的生成盒子層疊水平是0。盒子(除非是根元素)不會創建一個新的層疊上下文。這是起作用的反而是子元素的z-index值。第一個子元素的z-index大于第二個子元素的,所以會覆蓋。

3.CSS中層疊上下文和層疊水平

層疊上下文(stacking content)是HTML元素中的一個三維概念,表示元素在z軸上有了“高人一等”。

頁面根元素天生具有層疊上下文,稱之為"根層疊上下文"

z-index值為數值的定位元素也具有層疊上下文

層疊上下文中的每個元素都有一個層疊水平(stacking level),決定了同一個層疊上下文中元素在z軸上的顯示順序。幾乎所有的元素都有層疊水平,但是要放在層疊上下文中來看。

層疊水平和z-index不是一個東西。普通元素也有層疊水平,但z-index只在定位元素上起作用。

同一個層疊上下文中的層疊元素遵循“后來居上”“誰大誰上”的層疊原則。

層疊上下文幾個特性:

  • 層疊上下文可以嵌套(父元素中嵌套子元素),組成一個分層次的層疊上下文。
  • 每個層疊上下文和兄弟元素獨立:當進行層疊變化或渲染的時候,只需要考慮后代元素
  • 每個層疊上下文是自成體系的:當元素的內容被層疊后,整個元素被認為是在父層的層疊順序中

4.理解元素的層疊順序(stacking order)

層疊順序:元素發生層疊時候有著特定的垂直顯示順序。

著名的7階層疊水平(stacking level),用來判斷元素發生層疊時誰在上誰在下:

Paste_Image.png

層疊元素的意義:

規范元素重疊時候的呈現規則。

為何層疊順序是上面圖片中的樣子?比如:為何內聯元素會覆蓋浮動元素?

之所以是這樣的七階,是因為這樣更符合加載的功能和視覺呈現

一般來說,像background/border是用來裝飾的,塊狀元素、浮動元素都是用來布局的,而內聯元素絕大部分是內容:圖片、文字,因為內容是頁面最重要的部分,因此層疊必須水平要高,重要的東西越要往上面放!

demo :

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
       img{
        float: left;
        margin-right: -40px;
        width: 250px;
        height: 400px;
       }
    </style>
</head>
<body>
        ![](b.jpg)
        <span>
            以前浮動課學過,浮動設計的作用是實現文字環繞圖片的效果。如果文字和
            圖片發生重疊,顯然,是后面的文字要優先顯示的,因為,文字比圖片重要。
        </span>
</body>
</html>

這里把圖片變成了浮動元素,內容(內聯元素)覆蓋了圖片浮動元素,比浮動元素的層疊水平要高。

Paste_Image.png

demo:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
       .inline-block,.block{
           width: 400px;
           height: 200px;
           position: relative;
       }
       .inline-block{
           display: inline-block;
           background-color: olive;
           margin: -30px; 
       }
       .block{
           display: block;
           background-color: green;
       }
    </style>
</head>
<body>
    <div class="inline-block">
        display:inline-block
    </div>
    <div class="block">
        display:block;
    </div>
</body>
</html>
Paste_Image.png

內聯元素比塊狀元素的層疊水平高,上面的背景色覆蓋了下面的,但是下面的文字覆蓋了上面的背景色。這是因為:背景色的覆蓋是層疊順序,文字的覆蓋是后來居上原則。文字是inline元素和inline-block是平級的,所以這里要用到后來居上原則

5.z-index與層疊上下文(解釋z-index的實際行為表現)

三個行為要點:

1. 定位元素默認的`z-index:auto`可以看成是z-index:0
2.z-index不為auto的定位元素會創建層疊上下文;
3.z-index層疊順序的比較止步于父級層疊上下文;

第一個行為要點:定位元素默認的z-index:auto可以看成是z-index:0;

demo 1:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
       
       .img1,.img2{
            width: 200px;
            height: 400px;
       }
       .img1{

       }
       .img2{
           margin-left: -60px;
       }
    </style>
</head>
<body>
    ![](a.jpg)
    ![](b.jpg)
</body>
</html>
Paste_Image.png

根據后來居上原則后面的元素會覆蓋前面的元素

demo 2:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
       
       .img1,.img2{
            width: 200px;
            height: 400px;
       }
       .img1{
            position: relative;
       }
       .img2{
           margin-left: -60px;
       }
    </style>
</head>
<body>
    ![](a.jpg)
    ![](b.jpg)
</body>
</html>
Paste_Image.png

第一個圖片變成定位元素之后,前面的圖片又覆蓋了后面的,這是因為當變為定位元素后,沒有對z-index設置值,所以默認值為auto,從層疊順序上看,這時可以把z-index:auto看成是z-index:0。這時再對照七階層疊那個圖:

Paste_Image.png

第二個行為要點:z-index不為auto的定位元素會創建層疊上下文

demo:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
        .div2{
            position: absolute;
            background: blue;
            width: 200px;
            height: 400px;
            margin-left: 100px;
        }
        .div2 img{
            position: relative;   
            margin-left: -100px;
            z-index: -1;
        }
    </style>
</head>
<body>
   
    <div class="div2">
        ![](a.jpg)
    </div>
</body>
</html>
Paste_Image.png

絕對定位元素只是一個普通元素,并不具有層疊上下文。此時圖片的層疊上下文是頁面根元素。所以背景色會覆蓋圖片。

一旦給父元素z-index值為數值不為auto時,

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
        .div2{
            position: absolute;
            background: blue;
            width: 200px;
            height: 400px;
            margin-left: 100px;
            z-index: 0;
        }
        .div2 img{
            position: relative;   
            margin-left: -100px;
            z-index: -1;
        }
    </style>
</head>
<body>
   
    <div class="div2">
        ![](a.jpg)
    </div>
</body>
</html>

Paste_Image.png

當我們給父元素.div設置z-index:0;時,就創建了層疊上下文,此時圖片的層疊上下為文就變成了容器。z-index負值的層疊順序在層疊上下文元素的背景色之上。

Paste_Image.png

從層疊順序上講,z-index:auto可以看成z-index:0。但是從層疊上下文來講,兩者卻有著本質差異!本質差異:z-index:auto不可以創建層疊上下文,z-index:0可以。

第三個行為要點:z-index受限于層疊上下文

demo:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
       
       .img1,.img2{
            width: 200px;
            height: 400px;
       }
       .box1{
         position: relative;
         z-index: 0;
       }
       .box1 img{
          position: absolute;
          z-index: 99999;
       }
       .box2{
          position: relative;
          z-index: 1;
          margin-left: 120px;
       }
       .box2 img{
          position: absolute;
          z-index: -1;
       }
    </style>
</head>
<body>
    <div class="box1">
        ![](a.jpg)
    </div>
    <div class="box2">
        ![](b.jpg)
    </div> 
</body>
</html>
Paste_Image.png

可以看到盡管第一個圖片的z-index遠遠大于第二個圖片,但是由于第二個圖片的父元素的層疊順序大于第一個圖片父元素的層疊順序,所以最終的行為表現仍然是后面的覆蓋前面的。

6.其他CSS屬性與層疊上下文(不只是z-index)

1.頁面根元素天生具有層疊上下文,稱之為"根層疊上下文"。
2.z-index值為數值的定位元素(相對或絕對)也具有層疊上下文。
3.其他屬性......創建層疊上下文。

Paste_Image.png

demo 1:display:flex與層疊上下文

<!DOCTYPE html>
<html lang="en">
<head>
   <meta charset="UTF-8">
   <title>Document</title>
   <style>
       .box{
           background: blue;
           width: 300px;
           height: 500px;
           margin: 0 auto;
       }
       .box>div{
           z-index: 1;
       }
       .box>div>img{
           position: relative;
           z-index: -1;
           margin-left: -100px;
       }
   </style>
</head>
<body>
   <div class="box">
       <div>
           ![](a.jpg)
       </div>
   </div>
</body>
</html>

Paste_Image.png

由于.box不是層疊上下文元素,所以圖片沒有覆蓋背景色,此時圖片的層疊上下文為根元素。

當我們為.box設置display:flex之后:

Paste_Image.png

圖片覆蓋了背景色。

注意:給.box設置display:flex不是.box變為了層疊上下文元素,而是它的子項變成了層疊上下文元素

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
        .box{
            background: blue;
            width: 300px;
            height: 500px;
            margin: 0 auto;
            display: flex;
        }
        .box>div{
            z-index: auto;
        }
        .box>div>img{
            position: relative;
            z-index: -1;
            margin-left: -100px;
        }
    </style>
</head>
<body>
    <div class="box">
        <div>
            ![](a.jpg)
        </div>
    </div>
</body>
</html

Paste_Image.png

當對它的子元素的z-index值設置.box>div{ z-index: auto; }后,.box元素的子項就不再是層疊上下文元素了

demo 2 :opacity ≠ 1 與層疊上下文

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
        .box{
            background: blue;
            width: 300px;
            height: 500px;
            margin: 0 auto;
        }
        .box img{
            position: relative;
            z-index: -1;
            margin-left: -100px;
        }
    </style>
</head>
<body>
    <div class="box">
        ![](a.jpg)
    </div>
</body>
</html>

Paste_Image.png

當我們為.box元素設置opacity為0.5時:

Paste_Image.png

圖片顯示在了背景色上面,這是因為opacity ≠ 1的元素為層疊上下文元素。

demo 3 :transform ≠ none 與層疊上下文

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
        .box{
            background: blue;
            width: 300px;
            height: 500px;
            margin: 0 auto;
            transform: rotate(15deg);
        }
        .box img{
            position: relative;
            z-index: -1;
            margin-left: -100px;
        }
    </style>
</head>
<body>
    <div class="box">
        ![](a.jpg)
    </div>
</body>
</html>

Paste_Image.png

transform ≠ none的元素為層疊上下文元素.

......以上不過多贅述。

7.z-index與其它CSS屬性層疊上下文(非定位元素層疊上下文和z-index關系)

1.不支持z-index的層疊上下文元素的層疊順序均是z-index:auto級別(不支持z-index的層疊上下文,指的就是那些CSS屬性創建的層疊上下文)。

Paste_Image.png

舉個例子:

Paste_Image.png

上圖中img1、img2、img3、img4、img5依次相互覆蓋,img1對應七階層疊水平中的第五階,是inline水平元素,img2、img4、img5是不依賴z-index的層疊上下文,img3是z-index:auto,它們都對應第六階,屬于同階,遵循后來居上原則,依次覆蓋。

2.依賴z-index的層疊上下文元素的層疊順序取決于z-index值

?????依賴z-index值創建層疊上下文的情況:

1.position值為relative/absolute或fixed(部分瀏覽器);
2.display:flex|inline-flex容器的子flex項;

Paste_Image.png
Paste_Image.png

上圖中的.box元素是普通元素,它的子項才是層疊上下文元素,所以不僅被第一張圖片覆蓋,還被父元素的背景色覆蓋

Paste_Image.png

Paste_Image.png
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,702評論 6 534
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,615評論 3 419
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,606評論 0 376
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,044評論 1 314
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,826評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,227評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,307評論 3 442
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,447評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,992評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,807評論 3 355
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,001評論 1 370
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,550評論 5 361
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,243評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,667評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,930評論 1 287
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,709評論 3 393
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,996評論 2 374

推薦閱讀更多精彩內容

  • 問答題47 /72 常見瀏覽器兼容性問題與解決方案? 參考答案 (1)瀏覽器兼容問題一:不同瀏覽器的標簽默認的外補...
    _Yfling閱讀 13,776評論 1 92
  • z-index 與 css 定位屬性 z-index 只對定位元素有作用。 如果定位元素z-index沒有發生嵌套...
    soojade閱讀 880評論 0 2
  • 第一節:z-index基礎 較大的z-index會覆蓋較小的那個z-index元素 z-index:auto 默認...
    胖魚尾巴閱讀 1,030評論 0 0
  • 1.z-index簡介 (1) 概念 z-index屬性指定了元素與元素之間的z軸上的順序,而z軸決定元素之間發生...
    Bennt閱讀 24,002評論 2 10
  • CSS 定位 CSS有三種基本的定位機制:普通流,浮動,絕對定位(absolute, fixed):普通流是默認定...
    _空空閱讀 5,764評論 0 15