之前调元素的显示优先级时,只会默默的调z-index以达到效果,但有时不生效,又不知道根因。刚好详细了解到层叠上下文,可以解释此类问题。
在CSS2.1规范中,每个盒模型的位置是三维的,分别是平面画布上的X轴,Y轴以及层叠Z轴。 一般情况下,元素在页面上沿X轴Y轴平铺,我们察觉不到它们在Z轴上的层叠关系,而一旦元素发生堆叠,这时我们就能发现某个元素可能覆盖了另一个元素或者被另一个元素覆盖。 我们这里要讨论的层叠上下文(stacking context),就是HTML中的一个三维概念,即元素的z轴,层级越高越接近阅读者。
一般来讲有3种方法:
div {
width: 200px;
height: 200px;
}
.one {
background-color: blue;
}
.two {
background-color: green;
margin-top: -100px;
}
在示例代码中,我们创建了两个div,然后使其产生重叠,默认情况下后来居上,绿色的会盖住蓝色的。
下面我们给蓝色设置一个定位,如下:
.one {
background-color: blue;
position: relative;
z-index: 1;
}
由于设置了定位和z-index属性,所以蓝色的div就会创建一个层叠上下文,在Z轴上就“高人一等”。
除了层叠上下文,我们还需要了解两个概念:
这两个东西实际上都是用来描述:在同一层叠上下文中,元素在Z轴上的显示顺序(前一个是概念,后一个是规则)。
div {
width: 200px;
height: 200px;
}
.one {
background-color: blue;
position: relative;
z-index: 1;
}
.two {
background-color: green;
position: relative;
z-index: 2;
}
.item {
width: 100px;
height: 100px;
left: 200px;
top: 200px;
position: absolute;
}
在上面的代码中,one和two分别有自己的层叠山下文,但是two的层叠等级要比one高,之后我们可以看到,无论one中的子元素的z-index设置有多高,它始终被two的子元素覆盖,因为两个元素不在同一个层叠上下文中,比较的是所在层叠上下的等级。
.box1,
.box2 {
position: relative;
}
.child1 {
width: 200px;
height: 100px;
position: absolute;
background-color: blue;
top: 0;
left: 0;
z-index: 2;
}
.child2 {
width: 100px;
height: 200px;
position: absolute;
background-color: red;
top: 0;
left: 0;
z-index: 1;
}
在上面的示例中,.box1/.box2虽然设置了position:relative,但是没有设置z-index。所以.box1/.box2仍然是普通元素,所以.box1/.box2属于html元素的“根层叠上下文”中,也就是处于同一个层叠上下文中,根据层叠顺序谁的z-index值大,谁在上面。
box1,
.box2 {
position: relative;
z-index: 0;
}
因为设置z-index: 0后,.box1/.box2产生了各自的层叠上下文,这时候要比较.child1/.child2的层叠关系属于不同的层叠上下文进行比较,此时由各自所在的.box1/.box2的层叠关系来决定。 但是.box1/.box2的z-index值都为0,都是块级元素(所以它们的层叠等级、层叠顺序是相同的),这种情况下,在DOM结构中后面的覆盖前面的,所以.child2就在上面。
.box {
width: 200px;
height: 200px;
background-color: blue;
position: absolute;
}
.item {
position: absolute;
width: 200px;
top: 50px;
left: 50px;
z-index: -1;
}
.box1设置了position,但没有设置z-index,所以没产生层叠上下文,对于.item而言,找到的层叠上下文是html根元素。而依据层叠顺序,block块状水平盒子的层叠顺序高于z-index为负的。
而如果给.box设置z-index后,就会产生一个层叠上下文,此时对于图片.item而言,找到的层叠上下文是.box,根据层叠顺序图,background是处于最下层的,所以图片显示在上面。
parent
child
.box {
display: flex;
}
.parent {
width: 200px;
height: 100px;
background-color: red;
z-index: 1;
}
.child {
width: 100px;
height: 200px;
position: relative;
background-color: green;
z-index: -1;
}
.parent会变成一个弹性元素,成为一个层叠上下文元素。于是对于.child来讲找到的层叠上下文就是.parent了,而非html元素。 根据层叠顺序,background的层叠等级小于z-index值小于0的元素的层叠等级,所以.child在.parent上面。