在編寫css樣式代碼的時候,我們經常會遇到z-index屬性的使用,我們可能隻了解z-index能夠提高元素的層級,并不知道具體是怎麼實作的。本文就來總結一個由z-index 引發的層疊上下文和層疊順序相關知識點,有了這方面的了解,才能減少開發中遇到的bug,同時這也是面試中經常遇到的問題。
通常情況下,html 頁面被認為是二維的,相當于隻有 x 和 y 軸,因為文本、圖像和其他元素被排列在頁面上而不重疊。這種情況下隻有一個渲染程序,所有元素都知道其他元素所占用的空間。z-index 屬性可讓你在渲染内容時調整對象分層的順序。<code>z-index</code> 屬性設定了一個定位元素及其後代元素或 flex 項目的 z-order。 當元素之間重疊的時候, z-index 較大的元素會覆寫較小的元素在上層進行顯示。這樣似的html頁面變成了一個三維的空間。

根據上面的了解,我們不難實作如下的效果:
代碼段1如下:我們隻需要改變box盒子的z-index值的大小就會改變盒子的層疊順序。
初次看上面的代碼,會發現 z-index 值越大在z軸上就越靠上,離浏覽器螢幕越近。但是仔細思考,你會發現這裡存在很多疑惑:z-index是在任何元素上面都有效果嗎?難道z-index的值的大小直接影響到元素的層疊順序嗎?
我們再來看下下面的代碼段2:
效果如下:
産生這樣的效果,究竟是為什麼呢,明明box2-item1、box2-item2 的z-index屬性值更大,結果這兩個盒子會被覆寫了呢。要想徹底知道其中的緣由,我們需要知道層疊上下、層疊等級、層疊順序這幾個概念。
層疊上下文(Stacking context),是html頁面中的一個三維的概念,就是上面提到的 z-index 的産生,導緻頁面有了z軸。預設a-index值為 aotu ,即z軸的0點處,同時可以設定z-index為正值和負值,表示該層疊上下文元素在z軸距離螢幕的遠近。
層疊等級(stacking level),在同一個層疊上下文中,它描述定義的是該層疊上下文中的層疊上下文元素在<code>Z軸</code>上的上下順序。在其他普通元素中,它描述定義的是這些普通元素在<code>Z軸</code>上的上下順序。隻有在同一層疊上下文中,層疊等級才有意義,z-index優先級最高。産生層疊上下文的條件:
文檔根元素(<code><html></code>);
<code>position</code> 值為 <code>absolute</code>(絕對定位)或 <code>relative</code>(相對定位)且 <code>z-index</code> 值不為 <code>auto</code> 的元素;
<code>position</code> 值為 <code>fixed</code>(固定定位)或 <code>sticky</code>(粘滞定位)的元素(沾滞定位适配所有移動裝置上的浏覽器,但老的桌面浏覽器不支援);
flex (<code>flexbox</code> (en-US)) 容器的子元素,且 <code>z-index</code> 值不為 <code>auto</code>;
grid (<code>grid</code>) 容器的子元素,且 <code>z-index</code> 值不為 <code>auto</code>;
<code>opacity</code> 屬性值小于 <code>1</code> 的元素(參見 the specification for opacity);
<code>mix-blend-mode</code> 屬性值不為 <code>normal</code> 的元素;
以下任意屬性值不為 <code>none</code> 的元素:<code>isolation</code> 屬性值為 <code>isolate</code> 的元素;<code></code><code>isolation</code> 屬性值為 <code>isolate</code> 的元素;isolation屬性值為isolate的元素
<code>transform</code>
<code>filter</code>
<code>perspective</code>
<code>clip-path</code>
<code>mask</code> / <code>mask-image</code> / <code>mask-border</code>
<code>-webkit-overflow-scrolling</code> 屬性值為 <code>touch</code> 的元素;
isolation 屬性值為 isolate 的元素;
<code>will-change</code> 值設定了任一屬性而該屬性在 non-initial 值時會建立層疊上下文的元素(參考這篇文章);
<code>contain</code> 屬性值為 <code>layout</code>、<code>paint</code> 或包含它們其中之一的合成值(比如 <code>contain: strict</code>、<code>contain: content</code>)的元素。
在層疊上下文中,子元素同樣也按照上面解釋的規則進行層疊。 重要的是,其子級層疊上下文的 <code>z-index</code> 值隻在父級中才有意義。子級層疊上下文被自動視為父級層疊上下文的一個獨立單元。
總結:
層疊上下文可以包含在其他層疊上下文中,并且一起建立一個層疊上下文的層級。
每個層疊上下文都完全獨立于它的兄弟元素:當處理層疊時隻考慮子元素。
每個層疊上下文都是自包含的:當一個元素的内容發生層疊後,該元素将被作為整體在父級層疊上下文中按順序進行層疊。
層疊順序”(stacking order)表示元素發生層疊時按照特定的順序規則在<code>Z軸</code>上垂直顯示。由此可見,前面所說的“層疊上下文”和“層疊等級”是一種概念,而這裡的“層疊順序”是一種規則。
代碼段2中,因為box1 和 box2 盒子都設定了position :absolute,并且box1設定了z-index:1,使得根層級上下文中 box1層級等級高于box2,是以産生了下圖中左圖的效果。在box1 盒子中設定flex,而兩個子盒子box1-item1和box1-item2 預設的z-index值為auto,不會産生層級上下文關系,是以産生了下圖中中間的效果圖。在box2中設定了flex屬性,而裡面的 box2-item1 和 box2-item2 都設定了z-index值為10,産生了層級上下文,會高于box2 的Background 順序顯示,是以産生了下圖中有圖的效果。
以上就是本文的全部内容,希望給讀者帶來些許的幫助和進步,友善的話點個關注,小白的成長之路會持續更新一些工作中常見的問題和技術點。