注册

深入理解CSS中的z-index

深入理解z-index

MDN上的定义是z-index 属性设定了一个定位元素及其后代元素或 flex 项目的 z-order。 当元素之间重叠的时候, z-index 较大的元素会覆盖较小的元素在上层进行显示。

但是这个说明太含糊了,当遇到z-index不生效的情况时,就不知所以然了,最近也查看了很多和z-index相关的资料,决定把z-index相关知识系统性的梳理一遍.


以前我总是很片面的认为元素在Z轴上的层叠顺序只跟z-index值的大小有关, 属性值大的元素显示在上面、属性值小的元素显示在下面,但是就像下面, 为啥z-index不生效呢,明明box1的z-index属性值大于box2的.

c1dcd4fff41f2e758607e154fab1e14b.png
事实上z-index属性并非对所有元素都生效, 它仅对定位元素生效而且定位元素的prosition属性值不为static时才会起作用:
c8a23fada11086b5015b51d9d055e0ef.png

其实判断元素在Z轴的层叠顺序取决于两个方面: 元素所在的层叠上下文元素自身的层叠级别, 在此之前我们先了解一下这两个概念:

z-index

通常情况下,html页面可以被认为是二维的,因为文本,图像和其他元素被排列在页面上而不重叠。在这种情况下,只有一个渲染进程,所有元素都知道其他元素所占用的空间。


CSS 2.1 中, 所有的盒模型元素都处于三维坐标系中。 除了我们常用的横坐标和纵坐标, 盒模型元素还可以沿着“z 轴”层叠摆放, 当他们相互覆盖时,z轴顺序就变得十分重要。这意味着 CSS 允许你在现有的渲染引擎上层叠的摆放盒模型元素。 所有的层都可以用一个整数( z 轴顺序)来表明当前层在 z 轴的位置。 数字越大, 元素越接近观察者。Z 轴顺序用 CSS 的 z-index 属性来指定。z-index的属性值默认为auto,可设置值为一个整数、可为正整数也可以是负整数


09fa44aaf0975e7488ae11aaa5e20033.png

层叠上下文

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


那么如何才能创建层叠上下文呢?我在网上看到过一个, 总结的很好: 目前有三类方法创建层叠上下文



  • 元素自身就能创建的
  • 需要结合z-index才能创建的
  • 不需要z-index 就能创建的

一、元素自身形成层叠上下文


文档根元素(<html>)会自动形成一个层叠上下文, 不需要结合任何其他属性


二、需要配合z-index才能触发创建层叠上下文的


position值为 absolute(绝对定位)或 relative(相对定位)且 z-index 属性值不为 auto 的元素;


采用flex布局容器的子元素, 且子元素 z-index 属性值不为 auto 的元素;


三、不要配合z-index就能触发创建层叠上下文的


position值为 fixed(固定定位)或 sticky(粘滞定位)的元素;


透明度opacity属性值不为1的元素


转换transform属性值不为none的元素


滤镜filter属性值不为none的元素


上面列举出来的都是一些常用到的属性,当然还有其他的属性值设置也能触发形成层叠上下文,这里就不一一列举了,有兴趣的同学可以去MDN文档查看.这里我们需要注意的几点:



  • 层叠上下文可以包含在其他层叠上下文中, 由于根元素HTML本身就是一个层叠上下文,所以页面文档中的创建的层叠上下文都是HTML元素层级的一个子级
  • 当某个元素创建了层叠上下文后, 应当把它及其后代当成一个整体,去判断层叠顺序
  • 父子元素、兄弟元素都可能会处于同一层叠上下文中

层叠级别

在不考虑层叠上下文的情况下, 元素的层叠级别就是判断发生层叠时,元素在Z轴如何显示的依据, 下图就是著名的7阶层叠水平:

659fac59906764540996b5a87b9a8f00.png

background/border、负z-index元素、块级元素、浮动元素、行内/行内块元素、z-index为0元素、正z-index元素.

文本节点我们也看成是一个行内元素

判断层叠顺序

在理解了层叠上下文和元素层叠水平的概念后,现在我们就可以说说元素在Z轴上的层叠顺序到底是怎么回事了: 元素在Z轴上的层叠顺序取决于两个方面: 元素所在的层叠上下文、元素自身的层叠级别,如果抛开层叠上下文来判断元素在Z轴上的层叠顺序就是瞎胡闹


1. 当要比较的两个元素在同一层叠上下文时, 就按照元素自身的层叠级别, 如果级别相同时后则覆盖前者




  • 同一层叠上下文中的兄弟元素


a51d7a021adb028813178cfa3cc37f63.png
上图box1、box2都处在同一层叠上下文中(html元素形成的上下文) ,二者都是行内块元素,级别相同, 所以后者覆盖前者
1897f6597b103d8ed335950cd612babf.png
  • 上图box1、box2也都处在同一层叠上下文中(html元素形成的上下文),但box1是行内元素,box2是块级元素, 根据元素的层叠级别,行内元素要高于块级元素, 所以box1显示在box2上面; 但是有个奇怪的现象, box1只能覆盖box2的背景,却不能覆盖box2内的字体.......为啥呢? 其实这个现象我们在上面也有提到过: 文本节点我们也看成是一个行内元素, 由于行内元素的级别要高于background/border,所以box1不能覆盖box2元素内的文本节点.




  • 同一层叠上下文中的父子元素


    也有可能是父子元素会出现在同一层叠上下文中, 其实刚刚上面我们说的字体的例子,就可以看成是父子元素在同一层叠上下文中, 这里就不在另外举例啦




2. 当要比较的两个元素不在同一层叠上下文时, 需要先向上查找到两者所在的共同的且最近的层叠上下文,然后在根据第1条规则来判断




链接:https://juejin.cn/post/6967737753983254564

0 个评论

要回复文章请先登录注册