重拾CSS规范之z-index

What’s z-index

z-index 会为当前的盒创建层叠上下文,也会指定该盒在父级层叠上下文中的层叠等级。

What the fuck! 怎么越说越乱!什么是层叠上下文?什么是层叠等级?

一个页面我们平时看到的是平面的,我们感觉它就是一个水平面(二维)的东西。但是为什么元素互相之间覆盖,这就说明,它们在垂直方向上是有顺序的。一个盒创建了层叠上下文,就是给它自己划了一片自治区,下面的盒无论是排资论辈,抑或是创建了层叠上下文,都只能在这片区里面待着。

定位(position 不为 static)的盒和flex盒的子元素都会有一个层叠等级,这个层叠等级就是 z-index 值,默认值 auto 我们可以理解为 0 。这就是为什么其他的没有层叠等级,因为 z-index 对它们无作用。层叠等级就是用来排资论辈的,等级高的在上面,等级低的在下面。但是,同一父级层叠上下文的层叠等级才有意义。

层叠等级只需要理解就好,真正的重点是层叠顺序

层叠顺序

层叠顺序七阶图

页面中所有元素都脱离不开这张七阶图,有了它我们可以知道所有元素在z轴上的先后顺序。图中越是靠前的元素,它离我们的眼睛越近,覆盖其他元素的能力就越强。七阶层叠图示中的层叠顺序指的是同一层叠上下文中的元素的层叠顺序。

当然,这里还有两点需要补充一下:

  1. z-index越大,越靠前,这就是用层叠等级来排资论辈的。
  2. 层叠顺序、层叠等级(如果有的话)相同的两个元素,后面的会覆盖前面的。

上面以及后面要讲的 “靠前” 就是z轴上越高,层叠顺序也越高。

极易混淆易错点

子层叠上下文无法比父层叠上下文低

我们有时候会希望让子元素居于父元素下方,我们可能会立即想到给子元素设置一个比父元素更低的z-index,结果肯定得不到我们希望的效果。

回顾一下层叠七阶图,会发现,父层叠上下文的 background 处于第一阶,而子层叠上下文 z-index 为负,处在第二阶,子层叠上下文的层叠顺序在父层叠上下文之上!!!它们是父子层叠关系,不是兄弟层叠上下文,所以不能通过 z-index 来比较它们的层叠等级。

那如何才能让子元素在父元素之下呢?让父元素不产生层叠上下文,并且让子元素 z-index 为负就可以了。

层叠上下文不关心父子元素关系,它只关心父子层叠上下文。

不同上下文中的元素的比较不取决于自身

上面那句话可能看着拗口不好理解,那我们看一下下面的例子辅助理解一下。

我们可以看到 .inner1 元素的 z-index 设置到了 9999 , .inner2 元素的 z-index 设置到了 0 ,但是后者就是覆盖了前者,为什么呢?为什么呢?

我们前面说了,元素层叠顺序只能够在自身所处的层叠上下文中比较,那和其他上下文中的元素怎么比较呢?拼爹!!!

这确实是一个很有意思的词,我来解释一下,就是说,处于同一层叠上下文的 A,B 两个元素,它们都创建了各自的层叠上下文,如果 A 层叠等级高于 B ,那么 A 下面的所有元素在z轴上高于 B 下面的所有元素。

z-index:auto;与z-index:0;的异同

我们下面会介绍哪些元素会创建层叠上下文,但是不代表能够创建层叠上下文的元素就可以显式地设置 z-index 。这些元素中不能设置 z-index 的,他们最后的表现其实就是 z-index:auto;

z-index:auto;z-index:0; 的相同之处在于,计算层叠等级的时候指定为 autoindex 实际计算值就是 0 。不同之处在于, z-index:auto; 不能创建层叠上下文,但是 z-index:0; 却可以。

position:relative; 元素默认 z-index:auto; ,根据我们之前论证出来的,子层叠上下文无法比父层叠上下文低。上面的例子表明,
z-index:auto; 并不能创建层叠上下文。但是有个例外, position:fixed; 元素可以创建。

哪些元素可以创建层叠上下文

我们在这里呢,把它们分成两部分,第一部分是 CSS2.1 中定义的可以创建的,第二部分是 CSS3 中新增的。

CSS2.1 中规定的

  • 根元素 HTML
  • z-index 不为 auto 的定位元素——实际情况有出入,z-index:auto;与z-index:0;的异同 一节已经讲了

CSS3中新增的

  • z-index 值不为 autoflex 项(父元素 display:flex|inline-flex)
  • 元素的 opacity 值不是 1
  • 元素的 transform 值不是 none
  • 元素 mix-blend-mode 值不是 normal
  • 元素的 filter 值不是 none
  • 元素的 isolation 值是 isolate
  • will-change 指定的属性值为上面任意一个
  • 元素的 -webkit-overflow-scrolling 设为 touch

这里除了 flex 项,其他的都不能设置 z-index ,实际表现就是 z-index:0;


z-index 平时真是被我们滥用了,有时候为了做一个弹出层效果,就随便设置一个 z-index:9999; ,这是一个坏习惯,所以我们要尽可能的利用层叠顺序规则来更规范地实现效果。

小小的一个属性牵扯了这么多内容,深入理解CSS,下节更精彩。

热评文章