層疊上下文與z index

2021-09-14 01:17:39 字數 3531 閱讀 1561

z-index是咱們之前相對比較常用的乙個語法了,看起來比較簡單的樣子,實際上還真不難,因為這東西跟之前講的vertical-align不一樣,這個比較符合咱們的認知。

好了,不廢話,開始咱們的正式話題。

首先呢?咱們先要了解一下層疊上下文(stack context)是什麼呢,其實通俗來講,就是你看電腦的這個方向的乙個顯示順序,比如說,桌子上有一大堆紙,你對著它看的話,每一張紙,實際上你就可以理解為乙個層疊上下文中的乙個層疊順序(stack level),你能看到的,往往是最靠前的那幾張紙,後面的都被遮擋住了。

那麼,首先最簡單的一點。如果有有一摞的完全重合的值,你能看到的,往往都是最靠上的那張紙,也就是離你眼睛最近的那一張。然而對於咱們的z-index來說呢,值越大,也就相當於離你眼睛越近。在紙張裡的位置越靠上。 所以說,下面的**,你應該一看就能知道,哪個元素在哪個元素的前面。

.*****1 

.*****2

下面是結果圖,我想聰明如你,一定都猜到了。

那麼乙個問題又來了,z-index大的,一定會遮蓋住z-index小的嗎?不廢話,直接看下面的**。

.*****1 

.*****2

.*****3

你覺得哪個的層級最高呢?來看一下最終執行的結果把。

竟然不是.*****3在最上面,他似乎被.*****1給擋住了,按理來說,不是z-index越大的,層級越高嗎?出現這種情況到底是為什麼呢?

實際上,當z-index不為auto的時候,會自動建立乙個它自己的層級上下文,也就是說,*****1和*****2是同級的,他們都在根環境上下文上。但是*****3呢,是在*****2的環境上下文中,因為*****1的層級要比*****2要高,所以*****3的z-index哪怕再大,實際上也依然會被*****1給擋住的。

那麼,問題又來了,只有z-index不為auto時才會建立環境上下文嗎?答案肯定是否定的,實際上,咱們平時用到的不少css屬性,也會自動建立環境上下文,下面咱們就看下mdn對這一塊所列出來的一些屬性(本文更新自2019.3.25,如果看到此文時已經過了好幾個月,甚至是一兩年,推薦看英mdn頁面:

層級上下文建立條件:

transform

filter

perspective、

clip-path

mask / mask-image / mask-border

看了上面的列表,應該會明白為什麼我用z-index的時候,都會加position: absolute了吧。

那麼,如果z-index值相同時,會怎麼顯示呢?實際上,他會按照先後順序,後面的會覆蓋前面的。如下面的例子:

.*****1 

.*****2

那麼如果此時吧兩個div調換一下位置呢?那麼就會如下圖所示這樣。

黃色的小塊已經完全被藍色的給擋住了。不過如果是下面的**形式呢?

.*****1 

.*****2

此時的話,小黃塊將會被遮擋住,無論*****1在*****2的前面和後面,最後的結果都依然是一樣的。如下圖所示

但是呢,假如給.*****1加入乙個transform:scale(1)的話,他就會顯示出來,依然會按照先後順序,後面的先展示。

那麼,為什麼會這樣呢?

首先呢?在乙個層疊上下文中,實際上裡面不同的元素是有不同的層疊順序的,實際上下圖已經很好的說明了這一點,其從下往上依次為

background/border->負z-index->block塊狀水平盒子->float浮動元素->inline水平盒子->z-index:auto或者是z-index: 0->正z-index。

這個和咱們平時開發的表現是一致的。但是請注意z-index:auto和z-index: 0;的層級。他實際上是在inline水平元素的上面,因為定位元素,以及上面所列出來的css3的標籤,很多都是預設的z-index: auto; 所以上上個例子中,絕對定位的元素,始終會覆蓋其inline-block元素。但是呢,其inline-block元素由於新加了transform: scale(1)以後呢,實際上會預設乙個z-index: auto; 所以他們倆實際上層級就一致了,因此他們也就是遵循後來居上的乙個規則。誰在後面,誰就在靠上的位置。

同理,如果兩個元素分別為z-index: 0和z-index: auto; 的話,他們倆也遵循後來居上的規則,他們倆唯一的區別,就是z-index: 0會新建乙個層疊上下文,而z-index: auto;則不會;

另外,許多css3屬性中,比如說雖然transform預設是z-index: auto,但是其實際上也會新建層疊上下文,所以,這塊的話,你自己理解為有上面列出來的css3屬性時,預設附帶了乙個z-index: 0就可以了。

當然了,我再寫乙個關於負z-index的例子,作為大家的乙個小練習。不過我相信有了上面的鋪墊後,這個對於大家來說,應該就沒有很大的問題了

.*****1 

.*****2

此時結果如下圖

此時的話呢,由於*****2的z-index為-1,由於*****1和*****2都在乙個層疊上下文內(root),因此呢,*****2就自然的在*****1下面。也就如上圖所示。

但是如果給.*****1增加了乙個tranform: scale(1)呢,情況就會變得不太一樣,如下圖所示:

實際上就是因為增加了transform: scale(1)以後,實際上在*****1裡面新建了乙個層疊上下文,所以由於*****2是在*****1的層疊上下文裡,所以它自然就顯示出來了。無論其z-index值有多小。

好了,上面講的也差不多了,不過依然是為了方便大家的理解,在最後,我簡單的說一下其原理吧。

首先呢,其渲染樹是乙個深度優先的樹結構,然後呢,先渲染的實際上會比後渲染的層級要更高一些,這個就跟咱們用不同的塗料刷牆一樣,後刷的顏色總是會覆蓋先刷的那些顏色,實際上**渲染也是類似的。同時呢,在同級的時候,後面的要比前面的層級更高,實際上也是由於其遍歷方式決定的,這個我就不多說了。

推薦閱讀:

張鑫旭《css世界》中z-index一章

Z index 層疊上下文和層疊水平

層疊上下文是乙個概念上的東西,學過編譯原理的人應該對這裡的上下文很清楚,而層疊不過就是乙個詞罷了,解釋一下就是,根據層疊規則決定位置的乙個環境。還需要注意的一點是,具有層疊上下文的元素比普通元素要更靠近眼睛。層疊水平也是乙個概念上的東西,用大白話說就是 在乙個層疊上下文的環境下,裡面的元素在z軸上的...

層疊上下文

本文是我學習層疊上下文的總結。主要從以下途徑學習 mdn 張鑫旭大大的博文 層疊順序遵循下圖的規則,其中在張鑫旭大大的博文中提到inline block的層疊順序與圖中inline box是乙個level的 z index auto實際上和z index 0單純從層疊水平上看,可以認為是同一leve...

層疊上下文與層疊順序

參考文章 深入理解css中的層疊上下文和層疊順序 css深入理解之z index css深入理解之relative 先來弄清楚什麼是,層疊上下文。層疊上下文,英文稱作 stacking context 是html中的乙個三維的概念。如果乙個元素含有層疊上下文,我們可以理解為這個元素在z軸上就 高人一...