CSS中的Z-Index和堆疊上下文
之前對CSS中的Z-Index屬性一直存在著誤解。簡單的認為比較不同元素的Z-Index大小就可以決定不同元素在Z軸上的繪製順序了。其實最近遇到了一些問題,才發現CSS中的堆疊遠遠沒有那麼簡單。
先看看z-index的基本屬性:
Value: auto | <integer> | inherit Initial: auto Applies to: positioned elements Inherited: no Percentages: N/A Media: visual Computed value: as specified
首先明確一點,z-index只會對定位元素起作用,並且默認是不繼承的。對於定位元素來說,設置z-index可能會有如下的作用:
- 決定元素在當前堆疊上下文(stacking context)中的堆疊層級
當z-index的值為integer的時候,integer的值就指定了元素在當前的堆疊上下文中的堆疊層級,並且會建立一個新的堆疊上下文
- 決定元素是否建立一個新的堆疊上下文
除了html元素之外,z-index值為auto(default value)的元素不會生成新的堆疊上下文,並且在當前的堆疊上下文中的堆疊層級按照0來計算
這裡提到了一個概念堆疊上下文
,spec中其實對堆疊上下文的概念提及不多,我找到了以下的描述:
The order in which the rendering tree is painted onto the canvas is described in terms of stacking contexts.
Stacking contexts can contain further stacking contexts. A stacking context is atomic from the point of view of its parent stacking context;boxes in other stacking contexts may not come between any of its boxes.
我們可以了解到:
- 由堆疊上下文決定繪製的順序
- 堆疊上下文可以包含更多的子堆疊上下文
- 第三句話比較晦澀,按照我的理解其含義是: 從父級堆疊上下文的角度來看,不會關心子堆疊上下文的子孫的堆疊順序。而上只會關心子級之間的堆疊順序。
在CSS3中,除了z-index: integer的定位元素和根元素之外兩種途徑,有更多的方式來生成堆疊上下文:
- z-index不為auto的flex item. 即 父元素display為flex/inline-flex的元素
- opacity小於1的元素
- transform不為none的元素
- filter不為none的元素
- mix-blend-mode不為normal的元素
- position為fixed的元素
- etc...
按照標準的規定,在同一個堆疊上下文中,不同元素的繪製層次從遠到近按照下面的順序, 即使是沒有設置z-index的元素,繪製的時候也是會有層疊順序的:
- 背景和邊框
- 堆疊層級為負數的子堆疊上下文
- 處於文檔流中的,非inline, 非positioned的後代元素
- 非positioned的浮動元素
- 處於文檔流中的,非positioned的inline元素, 包括inline-table, inline-block.
- 堆疊層級為0的子堆疊上下文和堆疊層級為0的的定位後代元素。
- 堆疊層級為正數的子堆疊上下文
除了上面的堆疊層次之外,還有一點需要注意,當同一堆疊上下文中的元素之間堆疊層級一致,並且發生層疊的時候,在DOM流中處於後面的元素會覆蓋前面的元素。
推薦閱讀:
※Adobe Brackets 用來寫 HTML 和 CSS 有什麼優勢和技巧?
※CSS 偽元素有哪些不得了的用法?
※#00你認真學了css?
※深入常用CSS聲明(一) —— Background
TAG:CSS |