层叠上下文(Stacking Context)是指在 HTML 和 CSS 中,用于控制和管理元素层叠顺序以及呈现的一种机制。在一个网页中,许多元素(例如文本、图像、背景等)可能会重叠在一起,这时候就需要一种方法来决定哪个元素应该显示在前面,哪个元素应该显示在后面。
层叠上下文的原则是通过一系列的规则来确定元素的层叠顺序,这些规则可以根据元素的属性、内容、位置等来决定。每个层叠上下文都是一个独立的层叠环境,元素在不同的层叠上下文中可以相互叠加,但不会影响到其他上下文中的元素。
具象的比喻:你可以把层叠上下文元素理解为理解为该元素当了官,而其他非层叠上下文元素则可以理解为普通群众。凡是“当了官的元素”就比普通元素等级要高,也就是说元素在Z轴上更靠上,更靠近观察者。
)自动创建一个层叠上下文。z-index
,可以用来控制元素的层叠顺序,同时创建一个新的层叠上下文。display: flex
或 display: inline-flex
属性的元素的子元素会创建一个新的层叠上下文。display: grid
或 display: inline-grid
属性的元素的子元素会创建一个新的层叠上下文。::before
和 ::after
伪元素。层叠顺序(Stacking Order)指的是元素发生层叠时的垂直显示顺序。当元素位置互相重叠时,层叠顺序决定哪一个元素会覆盖在另一个元素的上方。
层叠顺序从后往前依次为:
需要注意的是:
就好比两个同职称的人,所在等级不一样,是没有可比性的。就好比董事长的秘书和什么经理科长的秘书虽然同为秘书,那等级一目了然。
例子一
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
div {
position: relative;
width: 100px;
height: 100px;
}
p {
position: absolute;
font-size: 20px;
width: 100px;
height: 100px;
}
.a {
background-color: blue;
z-index: 1;
}
.b {
background-color: green;
z-index: 2;
top: 20px;
left: 20px;
}
.c {
background-color: red;
z-index: 3;
top: -20px;
left: 40px;
}
</style>
</head>
<body>
<div>
<p class="a">a</p>
<p class="b">b</p>
</div>
<div>
<p class="c">c</p>
</div>
</body>
</html>
元素的position被设置为absolute,因此它们可以定位。p.a、p.b和p.c都位于各自的div内,并且应用了不同的z-index和定位属性。p.c元素的z-index最高,所以它在层叠顺序中位于最上面,即使它位于第二个div内,它仍然会覆盖在第一个div内的元素上面。
p.b元素位于第一个div内,因此它在第一个div内的p.a元素上面,并且由于p.b的定位,它距离div的左上角有20px的偏移。p.a元素位于第一个div内,因此它位于底部,被p.b和p.c元素所覆盖。最终,p.c元素在最上面,呈现为红色,p.b元素在中间,呈现为绿色,而p.a元素在底部,呈现为蓝色。
例子二
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
div {
width: 100px;
height: 100px;
position: relative;
}
.box1 {
z-index: 2;
}
.box2 {
z-index: 1;
}
p {
position: absolute;
font-size: 20px;
width: 100px;
height: 100px;
}
.a {
background-color: blue;
z-index: 100;
}
.b {
background-color: green;
top: 20px;
left: 20px;
z-index: 200;
}
.c {
background-color: red;
top: -20px;
left: 40px;
text-align: right;
z-index: 9999;
}
</style>
</head>
<body>
<div class="box1">
<p class="a">a</p>
<p class="b">b</p>
</div>
<div class="box2">
<p class="c">c</p>
</div>
</body>
</html>
例子三·
z-index: ‘auto’
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<style>
.box1,
.box2 {
position: relative;
z-index: auto;
}
.child1 {
width: 200px;
height: 100px;
background: #168bf5;
position: absolute;
top: 0;
left: 0;
z-index: 2;
}
.child2 {
width: 100px;
height: 200px;
background: #32c292;
position: absolute;
top: 0;
left: 0;
z-index: 1;
}
</style>
<body>
<div class="box1">
<div class="child1">child1</div>
</div>
<div class="box2">
<div class="child2">child2</div>
</div>
</body>
</html>
解析:
将 .box1,.box2的z-index设置为数值0,效果就不一样了
.box1,.box2 {
position: relative;
z-index: 0
}
例子四
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.parent {
width: 200px;
height: 100px;
background: #168bf5;
/* 虽然设置了z-index,但是没有设置position,z-index无效,.parent还是普通元素,没有产生层叠上下文 */
z-index: 1;
}
.child {
width: 100px;
height: 200px;
background: #32d19c;
position: relative;
z-index: -1;
}
</style>
</head>
<body>
<div class="box">
<div class="parent">
parent
<div class="child">child</div>
</div>
</div>
</body>
</html>
将父容器设置成flex布局
效果如下:
.box {
display: flex;
/* 此项设置会影响z-index */
}