阅读 437

CSS篇:为什么z-index值大的却在z-index小的下面?

前言

css为盒模型的布局提供了三种不同的定位方案

  • 正常文档流

  • 浮动

  • 定位

最后一种方案(特指绝对定位)将会把元素从正常文档流中完全移走,其最终的落脚点将取决于开发者。

通过设置 top,left,bottom 和 right 的值,你可以在二维空间中对元素进行定位,但 CSS 同时也允许你使用 z-index 把它放置在三维空间中。

表面看起来,z-index 似乎是一个很简单的属性,你给它设置哪个值,元素就会位于 y 轴的哪个位置,就这样。但它实际上并没有我们想象的这么简单,这个属性背后是一系列决定元素所在层级的规则。

z-index的基础概念

x 轴代表水平方向,y 轴代表垂直方向,z 轴则代表我们的目光向页面(屏幕)看进去的时候,各元素的布局情况。

屏幕是一个二维平面,所以我们实际上是看不到z轴的,z轴实际上是通过透视的形式展示的。也就是说,多个元素共享同一块二维平民啊时,友得元素在顶部,有的元素在底部,因此而感受到z轴的存在。

css允许我们给z-index设置三种值来决定某个元素在z轴方向上的位置。

  • auto(默认值) 堆叠顺序与父元素相等

  • number 元素的堆叠顺序,可以为正整数,负整数或者0

  • inherit 规定应该从父元素继承z-index属性的值

如果两个元素在定位之后共享同一块二维空间,那么在这块空间中,z-index越大的元素将会覆盖z-index较小的元素。

层叠上下文和层叠等级

什么是层叠上下文?

MDN定义:我们假定用户正面向(浏览器)视窗或网页,而 HTML 元素沿着其相对于用户的一条虚构的 z 轴排开,层叠上下文就是对这些 HTML 元素的一个三维构想。众 HTML 元素基于其元素属性按照优先级顺序占据这个空间。

什么是层叠等级?

在层叠上下文中,子级层叠上下文的 z-index 值只在父级中才有意义。子级层叠上下文被自动视为父级层叠上下文的一个独立单元。这样就产生了层叠等级,层叠上下文根据层叠等级决定元素在页面的层叠顺序。

在一个层叠上下文中,一共可能出现七个层叠等级,从最低到最高排列,依次是:

等级层叠元素
1背景和边框 :形成层叠上下文的元素的背景和边框,它是整个上下文中层叠等级最低的
2Z-Index 为负数 :设置了 z-index 为负数的子元素以及由它所产生的层叠上下文
3块级盒模型:位于正常文档流中的、块级的、非定位的子元素
4浮动盒模型 :浮动的、非定位的子元素
5内联盒模型 :位于正常文档流中的、内联的、非定位的子元素
6Z-index 为 0:设置了 z-index 为 0 的、定位的子元素以及由它所产生的层叠上下文
7Z-Index 为正数 :设置了 z-index 为正数的、定位的子元素以及由它所产生的层叠上下文,它是整个上下文中层叠等级最高的

总结:

  • 层叠上下文可以包含在其他层叠上下文中,并且一起创建一个层叠上下文的层级。

  • 每个层叠上下文都完全独立于它的兄弟元素:当处理层叠时只考虑子元素。

  • 每个层叠上下文都是自包含的:当一个元素的内容发生层叠后,该元素将被作为整体在父级层叠上下文中按顺序进行层叠。

Note:  层叠上下文的层级是 HTML 元素层级的一个子级,因为只有某些元素才会创建层叠上下文。可以这样说,没有创建自己的层叠上下文的元素会被父层叠上下文同化

示例

image.png

每个被定位的元素都创建了独自的层叠上下文,因为他们被指定了定位属性和 z-index 值。我们把层叠上下文的层级列在下面:

  • Root

    • DIV #4

    • DIV #5

    • DIV #6

    • DIV #1

    • DIV #2

    • DIV #3

注意 DIV #4,DIV #5 和 DIV #6 是 DIV #3 的子元素,所以它们的层叠完全在 DIV #3 中被处理。一旦 DIV #3 中的层叠和渲染处理完成,DIV #3 元素就被作为一个整体传递与兄弟元素的 DIV 在 root(根)元素进行层叠。

这几个div在层叠上下文的层叠等级依次是:DIV #1 > DIV #4 > DIV #6  > DIV #5 > DIV #3 > DIV #2 > Root。

案例展示

最后我们再来看一个案例,解释为什么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 {             padding: 20px;         }         .one,         .two,         .three,         .four {             position: absolute;             font-size: 50px;         }         .one {             width: 400px;             height: 400px;             background: red;             top: 100px;             left: 200px;             z-index: 10;         }         .two {             background: aqua;             width: 200px;             height: 200px;             top: 50px;             left: 50px;             z-index: 100;         }         .three {             background: blue;             width: 200px;             height: 200px;             top: 100px;             left: 100px;             z-index: 150;         }         .four {             background: green;             width: 200px;             height: 200px;             top: 250px;             left: 350px;             z-index: 50;         }     </style> </head> <body>     <div class="one">         1         <div class="two">2</div>         <div class="three">3</div>     </div>     <div class="four">4</div> </body> </html> 复制代码

来看看效果图

image.png

由于div.two和div.three在div.one中,所以它的z-index是和div.one的层叠上下文是相关的。实际表现出来的z-index是下面这样的:

元素z-index值
.one10
.two10.100
.three10.150
.four50

结论: div.one 和内部包含的一切将会在层级上低于 div.four,无论给 div.one 的子元素设置多大的 z-index,子元素的层级都无法超过 div.four。

最后: 看完了上面的这个案例,相信此时你对一个很大的z-index值却不能显示在一个小的z-index的值的上面有了理解了吧。

总结:定位元素可以创建新的层叠上下文,在这个上下文中的所有层叠等级,都会高于或者低于另一个层叠上下文的所有层叠等级。


作者:朽木白学前端
链接:https://juejin.cn/post/7034058863233990686


文章分类
代码人生
文章标签
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐