层叠上下文
stacking context是HTML中关于元素的三维的概念,它描述了用户视角(z轴),元素依据其属性的优先级顺序。
层叠水平
stacking level决定了在同一个 层叠上下文中元素在z轴的显示顺序,比较不在同一个层叠上下文中的元素的层叠水平没有意义。
层叠顺序
stacking order是规则。
层叠规则
- 谁大谁上
同一个 层叠上下文中的元素,都具有明确的层叠水平时,比如z-index,谁的数值大,谁在上面。
- 谁后谁上
同样的层叠顺序和层叠水平时,谁在后面,谁在上面。
- 儿子在上
在嵌套的层叠上下文中,永远是内部的层叠上下文在上面。
层叠上下文的创建
根元素
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并不能形成层叠上下文,所以意味着发生重叠时,元素都是同样的层叠水平,所有遵循谁后谁大原则。
论z-index:0与z-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: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没有使用flex布局,所以即使.flex-item有z-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使.box产生了层叠上下文,使用层叠顺序-儿子在上判断。
transform
.box {
width: 300px;
height: 300px;
background: red;
transform: translateY(1px);
}
使用了transform原理同opacity<1。