# 层叠上下文

## 层叠上下文 (Stacking Context)

![](/files/-Lj_eMysAt089OhtqfR6)

## 如何形成层叠上下文

* 根元素
* position值为absolute | relative，且z-index值不为 auto
* position 值为 fixed | sticky
* z-index 值不为 auto 的flex元素，即：父元素display: flex | inline-flex
* opacity 属性值小于 1 的元素
* transform 属性值不为 none的元素
* mix-blend-mode 属性值不为 normal 的元素
* filter、perspective、clip-path、mask、mask-image、mask-border、motion-path 值不为 none 的元素
* perspective 值不为 none 的元素
* isolation 属性被设置为 isolate 的元素
* will-change 中指定了任意 CSS 属性，即便你没有直接指定这些属性的值
* -webkit-overflow-scrolling 属性被设置 touch的元素

总结:

> 层叠上下文可以包含在其他层叠上下文中，并且一起组建了一个有层级的层叠上下文
>
> 每个层叠上下文完全独立于它的兄弟元素，当处理层叠时只考虑子元素，这里类似于BFC
>
> 每个层叠上下文是自包含的：当元素的内容发生层叠后，整个该元素将会在父级叠上下文中按顺序进行层叠

## 层叠顺序

1. 背景和边框：形成层叠上下文的元素的背景和边框。
2. 负z-index值：层叠上下文内有着负z-index值的定位子元素，负的越大层叠等级越低；
3. 块级盒：文档流中块级、非定位子元素；
4. 浮动盒：非定位浮动元素；
5. 行内盒：文档流中行内、非定位子元素；
6. z-index: 0：z-index为0或auto的定位元素， 这些元素形成了新的层叠上下文；
7. 正z-index值：z-index 为正的定位元素，正的越大层叠等级越高；

![](/files/-Lj_eMyz0bk2LsoZU4GL)

## demo

### 普通情况

```markup
<span class="red">Red</span>
<span class="green">Green</span>
<span class="blue">Blue</span>
```

```css
.red, .green, .blue {
  position: absolute;
  width: 100px;
  color: white;
  line-height: 100px;
  text-align: center;
}

.red {
/*   z-index: 1; */
  top: 20px;
  left: 20px;
  background: red;
}

.green {
  top: 60px;
  left: 60px;
  background: green;
}

.blue {
  top: 100px;
  left: 100px;
  background: blue;
}
```

![](/files/-Lj_eMz15VE2Nq3zMMfL)

### 在相同层叠上下文的父元素内的情况

```markup
<div class='first-box'>
  <span class="red">Red</span>
  <span class="green">Green</span>
</div>
<div class='second-box'>
  <span class="blue">Blue</span>
</div>
```

```css
.first-box{
   // z-index:1;  /* 父元素的层叠上下文一样 */
}

.second-box{
   // z-index:0;  /* 父元素的层叠上下文一样 */
}

div{
  position: relative;
}

.red,
.green,
.blue {
  position: absolute;  /* 都是定位元素 */
  width: 100px;
  color: white;
  line-height: 100px;
  text-align: center;
}

.red {
  top: 20px;
  left: 20px;
  background: red;
  // z-index:3;
}

.green {
  top: 60px;
  left: 60px;
  background: green;
  // z-index:2;
}

.blue {
  top: 100px;
  left: 100px;
  background: blue;
  // z-index:1;
}
```

![](/files/-Lj_eMzptgJBZ_G5Wlk4)

### 给子元素增加 z-index

```markup
<div class='first-box'>
  <span class="red">Red</span>
  <span class="green">Green</span>
</div>
<div class='second-box'>
  <span class="blue">Blue</span>
  <span class="gold">gold</span>
</div>
```

```css
div{
  position: relative;
}

.red, .green, .blue, .gold {
  position: absolute;
  width: 100px;
  color: white;
  line-height: 100px;
  text-align: center;
}

.red {
  top: 20px;
  left: 20px;
  background: red;
}

.green {
  z-index: 1;     /* 设置了正的z-index */
  top: 60px;
  left: 60px;
  background: green;
}

.blue {
  top: 100px;
  left: 100px;
  background: blue;
}

.gold{
  z-index: -1;     /* 设置了负的z-index */
  width: 140px;
  line-height: 140px;
  top: 40px;
  left: 40px;
  background: gold;
}
```

![](/files/-Lj_eN-8GEpup5MNcGho)

### 在不同层叠上下文的父元素内的情况

```markup
<div class='first-box'>
  <span class="red">Red</span>
  <span class="green">Green</span>
</div>
<div class='second-box'>
  <span class="blue">Blue</span>
</div>
```

```css
.first-box {
  position: relative;
  z-index: 1; /* 父元素的层叠上下文不一样 */
}

.second-box {
  position: relative;
  z-index: 0; /* 父元素的层叠上下文不一样 */
}

.red,
.green,
.blue {
  position: absolute;
  width: 100px;
  color: white;
  line-height: 100px;
  text-align: center;
}

.red {
  top: 20px;
  left: 20px;
  background: red;
  z-index: 10;
}

.green {
  top: 60px;
  left: 60px;
  background: green;
  z-index: 20;
}

.blue {
  top: 100px;
  left: 100px;
  background: blue;
  z-index: 999; /* 设置
```

![](/files/-Lj_eN-Dj9ZhNcrSPzpx)

### 给子元素设置 opacity

```markup
<div class='first-box'>
  <span class="red">Red</span>
  <span class="green">Green</span>
</div>
<div class='second-box'>
  <span class="blue">Blue</span>
  <span class="gold">gold</span>
</div>
```

```css
.first-box{
  opacity: .99;
}

div{
  position: relative;
}

.red, .green, .blue, .gold {
  position: absolute;
  width: 100px;
  color: white;
  line-height: 100px;
  text-align: center;
}

.red {
  top: 20px;
  left: 20px;
  background: red;
  z-index: 999;    /* 设置了很大的z-index */
}

.green {
  top: 60px;
  left: 60px;
  background: green;
  z-index: 999;    /* 设置了很大的z-index */
}

.blue {
  top: 100px;
  left: 100px;
  background: blue;
}

.gold{
  z-index: -1;     /* 设置了负的z-index */
  width: 140px;
  line-height: 140px;
  top: 40px;
  left: 40px;
  background: gold;
}
```

![](/files/-Lj_eN-JWFjN5_IsDBLa)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://jackmeng.gitbook.io/note/frontend/css/ceng-die-shang-xia-wen.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
