之前使用 z-index 停留在数值越大层级越高的认知,直到最近遇到一个问题。明明z-index最大了还是会被其他元素遮挡,这是为何呢?
层叠上下文
通常情况下,网页的布局都在二维平面里,但这种布局无法满足复杂的场景。css2.1中提出三维模型,除了x,y轴之外,增加了z轴,一个从屏幕垂直向外的坐标轴,所有的盒子都在三维模型中。
层叠上下文就是对这些 HTML 元素的一个三维构想。众 HTML 元素基于其元素属性按照优先级顺序占据这个空间。
如何声明一个层叠上下文
方法有很多,我只列举几个常用的,其他请参考MDN
- 文档根元素(html)
- postion显示指定为非
static,且z-index不为auto
层叠上下文特性
- 层叠上下文的子元素可以继续声明层叠上下文
z-index属性只有在同一层叠上下文中比较才有意义- 对于非层叠上下文的元素,被父层叠上下文同化
z-index
同一层叠上下文中
- 定位元素层数始终高于普通元素
- 同是定位元素
z-index越大,则层数越高,越在上层展示 z-index默认值是0z-index相同的情况下,按照元素出现顺序层叠
看下例子
<!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>
div.box1{
width: 500px;
height: 200px;
border: 1px solid rebeccapurple;
position: relative;
}
div.box11{
width: 50px;
height: 50px;
background-color: greenyellow;
position:relative;
}
div.box111{
width: 50px;
height: 50px;
background-color:skyblue;
position: absolute;
left: 200px;
z-index: 10;
}
div.box112{
width: 50px;
height: 50px;
background-color:gray;
position: absolute;
left: 210px;
z-index: 1;
}
div.box12{
margin-top: -10px;
width: 50px;
height: 50px;
background-color:orange;
}
</style>
</head>
<body>
<div class="box1">
<div class="box11">11
<div class="box111">111</div>
<div class="box112">112</div>
</div>
<div class="box12">
12
</div>
</div>
</body>
</html>

box11开启了定位所以层级要比box12高,即使box12在文档中的出现顺序比box11晚。
box111 和box112是同一层叠上下文的兄弟元素,z-index越高越先展示。
同一层叠上下文比较简单,也是常见的情况。
不同层叠上下文
不同层叠上下文则不可以简单通过 z-index来比较优先级,需要先找到共同的祖先层叠上下文,然后在同一祖先下找各自的第二祖先层叠上下文,直到找到自身,再比较第二祖先的优先级。
先看下错误示范
<!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>
div.box1{
width: 500px;
height: 200px;
border: 1px solid rebeccapurple;
position: absolute;
}
div.box11{
width: 50px;
height: 50px;
background-color: greenyellow;
position:absolute;
z-index: 10;
}
div.box111{
width: 50px;
height: 50px;
background-color:skyblue;
position: absolute;
left: 100px;
z-index: 1;
}
div.box12{
width: 50px;
height: 50px;
background-color:orange;
position: absolute;
top: 40px;
z-index: 1;
}
div.box121{
width: 50px;
height: 50px;
background-color:rebeccapurple;
position: absolute;
left: 100px;
z-index:10;
}
</style>
</head>
<body>
<div class="box1">
<div class="box11">11
<div class="box111">111</div>
</div>
<div class="box12">12
<div class="box121">121</div>
</div>
</div>
</body>
</html>

虽然 box121 的z-index要比box-111的值大,还是被box111覆盖了。
我们按照上面的思路来捋一下,box111和box121的共同祖先上下文是box1,box1下分别有box11是box111的祖先,box12 是box121的祖先,box111的z-index大于box-121的z-index,所以无论怎么增加box112的z-index都会被box111覆盖。
也就是说在同一层叠上下文中才认z-index,你的祖先被盖了冒了,那下面的所有子元素都低人一等。
再来看一个例子
我们只是把上面的 box12 的z-index 改成 auto,看下效果

box121 给祖先挣了口气,盖住了box111。因为auto会让开启定位的元素丢失层叠上下文,box111的第二祖先是box11而box121 的第二祖先变成了自身。box121的z-index等于box11的z-index,但是位置靠后,所以优先展示。
其实是box121盖住了box11,不是一辈儿的,不跟你玩了。
实际上,并不是所有元素都会开启层叠式上下文,只不过定位元素设置z-index:auto便不会开启上下文。box12是普通元素,也会是上面的情况。
那假如box121也不开启层叠上下文呢,那就相当于开启定位元素和普通元素的比较,自然是开启定位的元素层级更高了。
总之,不同层叠上下文比较同辈分的祖先的优先级即可。
本文解析了层叠上下文的概念及其实现方式,并详细解释了如何利用z-index属性来控制HTML元素的堆叠顺序。同时介绍了在不同层叠上下文中元素之间的层叠规则。
383

被折叠的 条评论
为什么被折叠?



