z-index与层叠上下文

本文转自掘金文章:为什么我写的z-index无效?,作者小蝉儿

1. 首先总结一下,什么是CSS层叠上下文?

  • 层叠上下文是HTML元素的三维概念,可以想象为一条垂直于视窗的z轴
  • 当元素创建了重叠上下文时,这个元素就有了一个z轴
  • 如果内部的子元素发生重叠,会依据自身属性优先级顺序占用z轴(重叠上下文)上的空间
  • 优先级最大的元素排在最上面,离用户也最近

2. 如何产生CSS层叠上下文?

  • html中的根元素<html></html>本身就是层叠上下文,称为根层叠上下文
  • position属性为非默认的static值,并设置z-index属性为具体数值
  • 一些CSS3属性也能产生层叠上下文
    • 一个 flex 元素,且其z-index 值不为 auto,也就是父元素 display: flex|inline-flex
    • 元素的 opacity 属性值小于 1
    • 元素的 transform 属性值不为 none
    • 元素的 mix-blend-mode 属性值不为 normal
    • 元素的 isolation 属性被设置为 isolate
    • 在 mobile WebKit 和 Chrome 22+ 内核的浏览器中,position: fixed 总是创建一个新的层叠上下文, 即使 z-index 的值是 “auto”
    • 在 will-change 中指定了任意 CSS 属性,即便你没有定义该元素的这些属性
    • 元素的 -webkit-overflow-scrolling 属性被设置 touch

3. 层叠顺序

image
具体解释为:

  1. 形成堆叠上下文环境的元素的背景与边框
  2. 拥有 z-index<0 的子堆叠上下文元素 (负的越高越堆叠层级越低)
  3. 正常流式布局,非 inline-block,无 position 定位(static除外)的子元素
  4. 无 position 定位(static除外)的 float 浮动元素
  5. 正常流式布局, inline-block元素,无 position 定位(static除外)的子元素(包括 display:table 和 display:inline )
  6. 拥有 z-index=0 的子堆叠上下文元素
  7. 拥有 z-index>0 的子堆叠上下文元素(正的越低越堆叠层级越低)
<div class="box1">1定位z-index<0</div>
<div class="box2">2块级元素</div>
<div class="box3">3浮动</div>
<div class="box4">4行内元素</div>
<div class="box5">5定位z-index=0</div>
<div class="box6">6定位z-index>0</div>
div {
  width: 100px;
  height: 100px;
  border: 1px solid #ccc;
}
.box1{
  position: relative;
  z-index: -1;
  background: antiquewhite;
}
.box2{
  margin-left: 50px;
  margin-top: -50px;
  background: aqua;
}
.box3{
  float: left;
  margin-left: 100px;
  margin-top: -50px;
  background: lightblue;
}
.box4{
  display: inline-block;
  background: lightcoral;
  margin-left: -50px;
}
.box5{
  background: lightgreen;
  position: relative;
  left:200px;
  top: -50px;
  z-index: 10;
}
.box6{
  background: lightsalmon;
  position: relative;
  left: 250px;
  top: -100px;
  z-index: 10;
}

image

4. z-index

记住一个原则

  1. 谁大谁上:定位元素的层级等级由z-index决定,z-index大的覆盖z-index小的。
  2. 后者居上:当元素的层叠等级一致、层叠顺序相同的时候,在DOM流中处于后面的元素会覆盖前面的元素。

z-index使用注意

z-index属性是用来设置元素的堆叠顺序,它可以被设置为正整数、负整数、0、auto,如果一个定位元素没有设置 z-index,那么默认为auto;此时不产生层叠上下文,当z-index设置了数值,此时就产生了一个层叠上下文。z-index的值越大,元素的层级越高,层级高的元素会覆盖在层级低的元素的上面。

  • z-index 只适用于定位(position 属性且值不为 static 时)或flex元素,对其他元素无效。
  • 当父元素设置了z-index属性时子元素的z-index属性只与同级元素和父级元素作比较时才有意义,与其他元素对比时无意义此时子元素与父元素外的所有的外部元素进行堆叠层级顺序对比时,都以父元素的z-index属性值为准进行对比,子元素本身的z-index属性值无效。所以如果你遇到 z-index 值设了很大,但是不起作用的话,就去看看它的父级层叠上下文是否被其他层叠上下文盖住了。
  • 当父元素未设置了z-index属性子元素的z-index属性与父元素外的所有的外部元素进行堆叠层级顺序对比时,都以元素本身的z-index属性值为准进行对比。

5. 如何让父元素盖住子元素?

这里很多人是不是认为直接让父元素的z-index大于子元素的z-index不就好了,可事实真是如此吗?
根据我们上面多次的实践,可以看到这样做是行不通的。父元素设置了z-index为数值,所以它产生了一个层叠上下文,此时子元素无论怎么设置z-index都不可能在父元素的下方。唯一可以实现的方法是将子元素的z-index设为负值,而父元素只要不产生层叠上下文就可以了。

posted @ 2023-03-24 14:46  pangqianjin  阅读(41)  评论(0编辑  收藏  举报