层叠上下文

269 阅读3分钟

层叠上下文

stacking context是HTML中关于元素三维概念,它描述了用户视角(z轴),元素依据其属性优先级顺序

层叠水平

stacking level决定了在同一个 层叠上下文中元素在z轴的显示顺序,比较不在同一个层叠上下文中的元素的层叠水平没有意义。

层叠顺序

stacking order规则
stacking order是规则。

层叠规则

  1. 谁大谁上

同一个 层叠上下文中的元素,都具有明确的层叠水平时,比如z-index,谁的数值大,谁在上面。

  1. 谁后谁上

同样的层叠顺序层叠水平时,谁在后面,谁在上面。

  1. 儿子在上

嵌套层叠上下文中,永远是内部的层叠上下文在上面。

层叠上下文的创建

根元素

html根元素天生具有层叠上下文。

具有明确z-index的定位元素

position: relative/absolute+z-index: 非auto会创建层叠上下文

z-index: auto

<div id="d1">
  <div id="d1-1"></div>
</div>
<div id="d2">
  <div id="d2-1"></div>
</div>
#d1 {
  position: relative;
  z-index: auto;
  #d1-1 {
    width: 200px;
    height: 400px;
    background: red;
    position: absolute;
  }
}

#d2 {
  position: relative;
  z-index: auto;
  #d2-1 {
    width: 400px;
    height: 200px;
    background: blue;
    position: absolute;
  }
}

position:relative/absolute+z-index:auto并不能形成层叠上下文,所以意味着发生重叠时,元素都是同样的层叠水平,所有遵循谁后谁大原则。

stacking-context-1

z-index:0z-index:auto

#d1 {
  position: relative;
  z-index: auto;
  #d1-1 {
    width: 200px;
    height: 400px;
    background: red;
    position: absolute;
    z-index: 2; // 创建层叠上下文
  }
}

#d2 {
  position: relative;
  z-index: 0; // 这里换成具体数值0
  #d2-1 {
    width: 400px;
    height: 200px;
    background: blue;
    position: relative;
    z-index: 1; // 创建层叠上下文
  }
}

论z-index:0与z-index:auto

z-index:auto不会创建层叠上下文z-index:0会。但他们层叠水平是一样的。

  • 任何元素都有层叠水平
  • 层叠水平是决定两个重叠元素谁在上面最关键的因素
  • 要确定一个元素的层叠水平,找其祖先元素确定层叠上下文是第一步

父元素的重要性

#d1 {
  position: relative;
  z-index: 1; // 父元素z-index:1
  #d1-1 {
    width: 200px;
    height: 400px;
    background: red;
    position: absolute;
    z-index: 2;
  }
}

#d2 {
  position: relative;
  z-index: 2; // 父元素z-index:2
  #d2-1 {
    width: 400px;
    height: 200px;
    background: blue;
    position: relative;
    z-index: 1;
  }
}

论`父元素`的重要性

特殊的css属性

flex布局

flex布局生成层叠上下文,需要满足两个条件:

  • 父元素display: flex
  • 子项目z-index: 具体数值
<div class="flex">
  <div class="flex-item">
    <div class="flex-item-inner"></div>
  </div>
</div>

案例1

.flex {
  
}

.flex-item {
  width: 300px;
  height: 300px;
  background: red;
  z-index: 1;
}

.flex-item-inner {
  width: 100px;
  height: 100px;
  background: blue;
  position: relative;
  left: 250px;
  z-index: -1;
}

flex&z-index

.flex没有使用flex布局,所以即使.flex-itemz-index:1,但.flex-item并没有生成层叠上下文,只是一个普通的block元素
.flex-item-inner是有层叠上下文的,此时.flex-item.flex-item-inner发生了重叠,但两者不在同一个层叠上下文中,故无法使用层叠准则层叠顺序可以帮助我们。

层叠顺序

根据层叠顺序block元素是在负z-index之上的。

案例2

.flex {
  display: flex; // +++
}

.flex-item {
  width: 300px;
  height: 300px;
  background: red;
  z-index: 1;
}

.flex-item-inner {
  width: 100px;
  height: 100px;
  background: blue;
  position: relative;
  left: 250px;
  z-index: -1;
}

.flex设置为flex布局.flex-item(z-index:1)就成了层叠上下文元素,此时在嵌套的层叠上下文中,依据层叠顺序-儿子在上规则。

层叠顺序

opacity<1

<div class="box">
  <div class="tar"></div>
</div>
.box {
  width: 300px;
  height: 300px;
  background: red;
}

.tar {
  width: 100px;
  height: 100px;
  background: blue;
  position: relative;
  left: 250px;
  z-index: -1;
}

继续

.box {
  width: 300px;
  height: 300px;
  background: red;
  opacity: 0.9;
}

opacity:不为1

opacity不为1使.box产生了层叠上下文,使用层叠顺序-儿子在上判断。

transform

.box {
  width: 300px;
  height: 300px;
  background: red;
  transform: translateY(1px);
}

transform

使用了transform原理同opacity<1