[toc]
## 什么是層疊上下文
層疊上下文,英文為`stacking context`,
當一個元素具備層疊上下文,這個元素在**Z軸**上就"高人一等"
我們可以把層疊上下文理解為一種"層疊結界",自成一個**小世界**(**每一個小世界由7個階層組成,發生重疊時,階層高的覆蓋階層低的**)。
在這個小世界可能有其他的"層疊結界",而自身也可能處于其他"層疊結界"中。
### 創建層疊上下文
和BFC塊狀格式化上下文一樣,層疊上下文也基本上是由一些特定的CSS屬性創建的,主要分為3個流派。
- 天生派:頁面根元素天生具有層疊上下文,稱為根層疊上下文
- 正統派:z-index值為數值的定位元素的傳統“層疊上下文”
- 擴招派:其它CSS3屬性
#### zindex:auto
沒有手動指定一個z-index值的話,會設置為auto,在層疊順序上位于第6階
因為所有元素都處于`根元素`這么個層疊上下文中,故所有元素默認z-index皆為auto
#### 定位元素與傳統層疊上下文
當元素定位時(absolute/fixed/relative)時,只要`z-index`的值**不**為auto,那么這個元素就會成為一個新的層疊上下文,形成層疊結界。
另外需要注意的是**Chrome**下,只要是**fixed**固定定位的元素就會生成一個新的層疊上下文。
#### CSS3新屬性創建層疊上下文
滿足以下CSS3屬性值的都會創建層疊上下文
1. 元素為flex布局元素(父元素display:flex|inline-flex),同時z-index值不為auto
2. 元素的opacity值不是1
3. 元素的transform值不是none
4. 元素的mix-blend-mode值不是normal
5. 元素的filter值不是none
6. 元素的isolation值是isolate
7. 元素的will-change屬性值為上面的2~6的任意一個(如will-change:opacity、will-change:transform等)
8. 元素的-webkit-overflow-scrolling設為touch
CSS3新屬性創建的層疊上下文**除卻**flex,其它**都**不能使用`z-index`,他們的層疊順序為第六階。
## 什么是層疊水平
層疊水平,英文為`stacking level`,
決定了同一個層疊上下文中元素在**Z軸**上的**顯示順序**。
(這意味著一個層疊上下文**中的**元素不能脫離"層疊結界"和另外一個層疊上下文中的元素較量層疊水平,而是由層疊上下文元素之間相互較量)
>[danger] 層疊水平!==z-index,
>
>**z-index**只在**定位元素**和**flex**盒子的孩子元素身上有效
>
>而**層疊水平**所有的元素的存在(至少都有一個根元素作為層疊上下文)
>
### 層疊順序
層疊順序是層疊水平的具體實現規則,英文稱之為`stacking order`
層疊順序一共**7層**,由下層到上層依次為
-->層疊上下文のbackground/border
-->負z-index
-->block塊狀水平盒子
-->float浮動盒子
-->inline水平盒子
-->z-index:auto(比如absolute的元素不設置z-index)或則z-index:0,又或則不依賴z-index的層疊上下文
-->正index
>**注意:**
>inine水平盒子指的是包括inline/inline-block/inline-table元素的層疊順序,它們都是同等級別的
>
#### z-index為0和auto
第六階層需要注意的是,
元素一旦成為定位元素,其z-index會**自動生效**,也就是`z-index:auto`,它相當于就是`z-index:0`,
**但是**z-index:0和z-index:auto有一點本質上的不同在于:
z-index:0會生成一個**新**的層疊上下文

(可以發現兩個div中的img因為處于同一個層疊上下文中,So層疊順序由z-index決定,故我們看見的是第一個div中的img)
但如果我們將第一個div的zindex設置為0

(可以發現img中的z-index不管用了,層疊按照層疊準則的第二條,后來居上原則進行)
這是為什么呢?
因為`z-index:0`生成了一個新的層疊上下文,對內部(這個新的層疊上下文里的元素)而言,就形成一個**結界**,里面的元素無法再和外面的層疊水平進行**直接**較量,而是由各自的頭頭進行較量
而此時第一個img的頭頭也就是第一個div的z-index為0,而第二個img的頭頭div此時沒有設置z-index,z-index自動生成值為auto,
然auto和0的層疊水平是一樣的,故層疊順序由`層疊準則`的第二條決定,誰在后面誰就在上面。
#### z-index為負值
z-index為負值時有不少應用,
比如css3屬性創建的層疊上下文是不能使用z-index值調整層疊順序的(只有定位元素和flex子項可),但我們可以調整那一個不是由css3屬性創建的層疊上下文的元素的z-index值為負值從而達到目的
>[info] css3屬性創建的層疊上下文元素本身處于第六階,而z-index負值處于第二階


另外

可以發現圖片跑到包裹它的div盒子的下邊去了,為什么呢?
因為此時div元素與img是處于同一層疊上下文中的,故誰處于**7層層疊順序**的上層,誰就在上面。
而`block元素層`是高于`z-index:負值層`的,故圖片在下面
但如果此時我們讓這個div元素形成一個新的層疊上下文,那么此時img就成了這個新的層疊上下文中的一部分,
那么此時div就算作第一階`層疊上下文のbackground/border`,是要低于第二階的`負z-index`的

(Chrome下fixed固定定位的元素無需z-index:非auto,就能生成一個層疊上下文)
### 層疊準則
當元素發生層時,其覆蓋關系遵循下面兩條準則
- 誰大誰上:當具有明顯的層疊水平標識的時候,如生效的z-index屬性值,在同一個層疊上下文領域,層疊水平值大的哪一個覆蓋小的那個一個。
- 后來居上:當元素的層疊水平一致、層疊順序相同的時候,在DOM流中處于后面的元素會覆蓋前面的元素
## 總結
小世界——層疊上下文
每一個小世界擁有7個階層,同一個小世界中,兩個元素發生重疊時,處于高階層的元素會覆蓋低階層的元素。
如果兩個元素階層也是一樣的,那么會根據`層疊準則`進行覆蓋。
- 空白目錄
- 未處理
- webpack中的css模塊化
- CSS預處理器
- 效果
- 元素裝飾與美化
- 顏色
- checkbox
- img
- background
- clip-path
- 字體
- 文本控制
- text-indent
- letter-spacing
- word-spacing
- word-break和word-wrap
- white-space
- text-align
- text-decoration
- text-transform
- first-letter
- first-line
- 有關CSS百分單位的那些奇葩事兒
- 破壞性、包裹性、塊狀化
- 強大的absolute
- padding
- relative
- 繼承性
- fixed
- float
- BFC
- z-index
- overflow
- clip
- 最佳可訪問性隱藏
- 關于scrollHeight/Width
- 包含塊
- margin
- 布局系統
- 雜
- Flex
- Grid
- 自定義布局系統
- gutter實現思路
- 選擇器
- 偽元素和偽類
- css3
- appearance
- CSS2.1
- tmp
- 未定義行為
- 焦點元素
- outline輪廓
- 替換元素
- 盒子模型
- 塊級元素/盒子
- 標記盒子
- 容器盒子(內在盒子)
- 內聯元素/盒子
- 字母X
- line-height
- vertical-align
- font-size
- 內聯元素盒子模型新解
- line-height定義
- line-height與行內框盒子模型
- line-height與內聯元素的高度機制
- line-height值
- line-height與圖片
- vertical-align支持的屬性值及組成
- vertical-align起作用前提
- vertical-align與圖片
- vertical-align與line-height
- vertical-align前后不一的行為表現
- vertical-align實際應用
- line-height與height
- width/height與auto
- 最小內容寬度
- 最大內容寬度
- min/max-width/height注意事項
- 流:外部尺寸與內部尺寸
- 流體布局下的寬度分離原則
- height:auto
- 瀏覽器渲染原理
- 移動端