z-index
前言
在最近官网的开发中,在图片元素相互堆叠的时候经常出现错误,不好好搞清楚 Z-index 的话,以后的工作就依旧要话很大的经历去百度,去找为什么图层顺序错误。因此写了这一片方便大家理解 z-index 到底是怎么运作的
基本规则
规则一:z-index 只会对脱离文档流的定位起效,也就是在 position:relative,absolute,fixed 下,z-index 才生效。
规则二:兄弟标签情况下,z-index 数值相同时,标签在下面的,图层更高。
规则三:z-index 数值越大越图层越高,越小图层越低
规则四:z-index 数值为负值时,该标签图层会低于 z-index 为默认值(不设置 z-index)的标签图层
这里盒子 1,2都没有设置 z-index,而标签在 <body>
最下方的盒子 3 则在所有盒子的下方。如果此时盒子 2设置了 z-index 为-1,则根据规则二可得,盒子 2在盒子 3下面
这样兄弟标签的 z-index 显然简单,但是**如果子元素也设置 z-index,父元素也设置 z-index,兄弟标签及其子元素也有 z-index 怎么办?**在复杂的项目中,仿佛全世界都加了 z-index,如何知道谁在谁上面,从而在布局页面的时候不会乱掉呢?
重点规则
规则五:子标签只有在父级标签没有设置 z-index 时,其 z-index 为负数才能在在父级标签图层下方,否则图层永远在父级标签上方
这里我们可以看到即使父级标签 z-index 大于子级标签,父级还是在底层,只要父级设置了 z-index,那么永远在子级标签图层的下方
规则六:非根 z-index 图层高度受制与父级的 z-index
这里得先解释什么是根 z-index,就是这个标签的祖先标签没有设置过 z-index,那么后代 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" />
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.js"></script>
<title>test</title>
<style>
div {
position: absolute;
box-shadow: 0px 0px 1px 2px;
}
.box:nth-child(1) {
width: 300px;
height: 300px;
background-color: cadetblue;
}
.box:nth-child(2) {
width: 300px;
height: 300px;
background-color: orange;
left: 150px;
top: 150px;
}
.box-child1 {
width: 150px;
height: 150px;
left: 70px;
top: 70px;
background-color: green;
}
.box-child2 {
width: 150px;
height: 150px;
left: 60px;
top: -50px;
background-color: yellow;
}
</style>
</head>
<body>
<div class="box">
盒子1
<div class="box-child1">盒子1的孩子</div>
</div>
<div class="box">
盒子2
<div class="box-child2">盒子2的孩子</div>
</div>
<script></script>
</body>
</html>
此时所有的 div 都没有设置任何的 z-index,这里当我们给 label 盒子 1 的孩子,也就是<div class="box-child1">
加上 z-index 为 1 时,我们可以看到 label 盒子 1 的孩子处在所有图层的最上方。
此时,当我们给 盒子 1 设置 z-index 后,事情就奇怪了起来
我们发现,本来在图层最上方的盒子 1 的孩子 变成了最开始的样子了!
这里的原因, label 盒子 1 的孩子 受到了盒子 1的限制,从根 z-index,变成后代 z-index,后代 z-index 只能在祖先 z-index 的空间中上下堆叠,没有办法超出祖先 z-index 堆叠 空间
也就是说,因为盒子 1 设置了 z-index 为 0,此时图层在盒子 2下方,因此无论 盒子 1 的孩子 的 z-index 值数值多大,都没有办法在盒子 2的上方。
说到这里可能你还是不太理解,那么我们做看几个例子就知道了,我们现在给 盒子 1 的孩子 添加一个后代标签,代码如下
<!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" />
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.js"></script>
<title>test</title>
<style>
div {
position: absolute;
box-shadow: 0px 0px 1px 2px;
}
.box:nth-child(1) {
width: 300px;
height: 300px;
background-color: cadetblue;
}
.box:nth-child(2) {
width: 300px;
height: 300px;
background-color: orange;
left: 150px;
top: 150px;
}
.box-child1 {
width: 150px;
height: 150px;
left: 70px;
top: 70px;
background-color: green;
}
.box-child2 {
width: 150px;
height: 150px;
left: 60px;
top: -50px;
background-color: yellow;
}
.box-grandson {
width: 70px;
height: 70px;
left: 120px;
top: 50px;
background-color: red;
}
</style>
</head>
<body>
<div class="box">
盒子1
<div class="box-child1">
盒子1的孩子
<div class="box-grandson">盒子1的孙子</div>
</div>
</div>
<div class="box">
盒子2
<div class="box-child2">盒子2的孩子</div>
</div>
<script></script>
</body>
</html>
此时 label 盒子 1 的孙子出现了,在中间那一点点红色的地方,我们能清楚的知道,红色处在在所有图层的正中间
如果此时 label 盒子 1 的孙子是根 z-index,我们给它设置 z-index 为 999,那么它就会到最上层,因为此时所有根 z-index 中它的数值最大,这里其实设置 1 就会到最上层。
让我们把 label 盒子 1 的孩子 z-index 设置为 1,让 label 盒子 2 的孩子 z-index 设置为 2
运用下我们之前写的规则
-
首先根据规则三, label 盒子 1 的孩子 的 z-index 小于 label 盒子 2 的孩子,因此 label 盒子 1 的孩子 在 label 盒子 2 的孩子下层,
-
根据规则六 , label 盒子 1 的孙子 的父级 label 盒子 1 的孩子 有了 z-index,由于 label 盒子 1 的孩子 图层低于 label 盒子 2 的孩子,所以 label 盒子 1 的孙子 图层低于 label 盒子 2 的孩子
-
根据规则五, label 盒子 1 的孙子 图层在 label 盒子 1 的孩子 上方
那么图层由高到低就是 label 盒子 2 的孩子 》 label 盒子 1 的孙子 》 label 盒子 1 的孩子 与上图显示的结果一致。
最后,让我们逆着来试试。
我们想让图层顺序为橙色 》黄色》绿色》红色》青色,那么应该怎么做?
首先是 label 盒子 1 orange 》 label 盒子 2 的孩子 yellow,根据规则五,label 盒子 1 orange 不设 z-index,label 盒子 2 的孩子 设置 z-index 为负数,结果如下
此时实现了 label 盒子 1 orange 》 label 盒子 2 的孩子 yellow,但是黄色在最底层,要让黄色高于剩下的颜色,那么根据规则二以及规则六,我们让 label 盒子 1 的 z-index 为-2(其实-1 就行),就能使得剩下的所有颜色都低于 label 盒子 2 的孩子的图层,结果如下
那么最后,还剩让 label 盒子 1 的孩子 大于 label 盒子 1 的孙子,那么根据规则五 ,label 盒子 1 的孩子 不设置 z-index,label 盒子 1 的孙子 的 z-index 设置为-1,就能达到我们最后的效果了。
最后
如果你细心看下来,并且把代码复制下来自己试了试,就发现 z-index 也不过如此,网上看了很都在说什么堆叠上下文,一开口就是头疼得不行的术语,实在是令我感到难受,提出规则六就是试图解释这个所谓的堆叠上下文。
或许换个方式解释规则六会更加生动,在我看来,z-index 就像是每个社会上的人,只有脱离了父母完成人格独立,才够去广阔的天地奔驰,与所有人、事物一教高下,而依托于父母的 z-index 就只能在父母提供的范围中蹦跶,父母什么层次,孩子也就什么层次。
非根 z-index 永远无法超越父级 z-index,父级 z-index 低人一层,非根 z-index 便低人一层,哪怕是 z-index:999999 也无法改变。
好了,讲个简单 CSS 知识开始往文章里灌鸡汤了。那么这篇文章到此为止!希望你们有所收获!