# 层叠上下文

元素的展示，并不是`z-index`来判断，这只是其中一个重要的元素。

`z-index`可以表示层叠层级，但是这个有个前置条件，那就是他是否存在层叠上下文。

## 那么什么是层叠上下文呢？

怎么说呢，就是看当前有层级的元素是否在层叠的父元素。说的比较简单粗暴。

## 那么层叠上下文是如何表现的？

比较简单的方式是 定位元素与层级所组成的上下文。

定位元素就是不为默认(`static`)的`position`。层级也就是`z-index`了。

看下面一个例子：

```markup
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />

  <title>层叠上下文测试</title>
  <style>
    .con {
      position: absolute;
      z-index: 1;
    }
    #root {
      position: relative;
      background: red;
      height: 200px;
      width: 200px;
      z-index: 3;
    }

    #sub {
      position: absolute;
      background: blue;
      height: 200px;
      width: 200px;
      top: 10px;
      z-index: 2;
    }
  </style>
</head>

<body>
  <div class='con'>
    <div id='root'>root</div>
  </div>
  <div class='con'>
    <div id='sub'>sub</div>
  </div>
</body>

</html>
```

你觉得上面展示出来的效果是什么样的？

> sub这个div覆盖在了root这个div上面.

为啥？这就是因为 层叠上下文的原因。譬如你把`.con`这个内的两个属性去除其中一个，那么红色的框子就会在上面了。

那么层叠上下文有哪些特性呢？

有两个黄金法则，你可以记一下：

1.  谁大谁上

    在同一个层叠上下文层级的时候，谁的层叠水平值大，那么谁就显示在上面。
2.  后来居上

    当元素的层叠水平一致、层叠顺序相同的时候，在DOM流中处于后面的元素会覆盖前面的元素。

## 这样就创建层叠上下文了？

那是在css3之前的方式。现在又多了几个，各位可以亲自试试看。

1. z-index值不为auto的flex项(父元素display:flex|inline-flex).
2. 元素的opacity值不是1.
3. 元素的transform值不是none.
4. 元素mix-blend-mode值不是normal.
5. 元素的filter值不是none.
6. 元素的isolation值是isolate.
7. will-change指定的属性值为上面任意一个。
8. 元素的-webkit-overflow-scrolling设为touch.

这几个你可以试试看，有没有什么不一致的地方。

参考：

> [深入理解CSS中的层叠上下文和层叠顺序](https://www.zhangxinxu.com/wordpress/2016/01/understand-css-stacking-context-order-z-index/)
