z-index

z-index 属性只是影响层叠顺序属性的一个,还有其他的属性影响层叠规则。z-index 只能影响定位元素和 flex 盒子的孩子元素。

理解层叠上下文和层叠水平

层叠上下文

层叠上下文(stacking context),是 HTML 中一个三维的概念。

层叠水平

层叠水平(stacking level),决定了同一个层叠上下文中元素在 z 轴上显示的顺序。

理解元素的层叠顺序

在 CSS2.1 时,层叠顺序如图一。

image.png
图一 CSS 世界层叠顺序规则

  • 位于最下面的 background/border 特指层叠上下文元素的边框和背景色。每一个顺序规则仅适用于当前层叠上下文元素。
  • inline 水平盒子指包括 inline/inline-block/inline-table 元素的“层叠顺序”。
  • 单从层叠水平 z-index:0 和 z-index:auto 可以看成一样的。但是二者子啊层叠上下文领域有着明显的区别。

为什么内联元素的层叠顺序比浮动元素和块级元素要高?

image.png
图二 CSS 世界层叠顺序类型标注

background/border 为装饰属性,块级元素和浮动元素一般用作布局,而内联元素是内容。网页是以图文显示为中心的,所以内联源的层叠顺序更高。

务必记住的层叠规则

当元素发生层叠时,其覆盖遵循以下规则:

  • 谁大谁上:当有明显的水平标识的时候,如 z-index,在同一水平上下文中,层叠水平值大的那个覆盖小的。
  • 后来居上:当元素的层叠水平一致、层叠顺序相同时,在 DOM 流中出于后面的元素会覆盖前面的元素。

深入了解层叠上下文

层叠上下文的特征

层叠上下文元素有如下特征:

  • 层叠上下文的层叠水平比普通元素要高。
  • 层叠上下文可以阻断元素的混合模式。
  • 层叠上下文可以嵌套,内部层叠上下文及其所有元素均受限于外部的“层叠上下文”。
  • 每个层叠上下文和兄弟独立。
  • 每个层叠上下文自成体系,当元素发生层叠时,整个元素被认为是子啊父层叠上下文的层叠顺序中。

层叠上下文的创建

和块状格式化上下文一样,层叠上下文也基本上是由一些特定的 CSS 属性创建的。我总结为 3 个流派。

  1. 天生派:页面根元素天生具有层叠上下文,称为根层叠上下文。
  2. 正统派:z-index 值为数值的定位元素的传统“层叠上下文”。
  3. 扩招派:其他 CSS3 属性。

  4. 根层叠上下文

根层叠上下文指的是页面根元素,可以看成是元素。因此,页面中所有的元定处于至少一个“层叠结界”中。

  1. 定位元素与传统层叠上下文

对于 position 值为 relative/absolute 以及 Firefox/IE 浏览器(不包括 Chrome 器)下含有 position:fixed 声明的定位元素,当其 z-index 值不是 auto 的时候,会层叠上下文。

层叠上下文与层叠顺序

一旦普通元素具有了层叠上下文,其层叠顺序就会变高。它的层叠顺序需要分两种情况讨论:

  • 如果层叠上下文元素不依赖 z-index 数值,则其层叠顺序是 z-index:auto,可看成 z-index:0 级别;
  • 如果层叠上下文元素依赖 z-index 数值,则其层叠顺序由 z-index 值决定。 我们上面提供的层叠顺序图实际上还缺少其他重要信息。我又花工夫重新绘制了一个更完整的 7 阶层叠顺序图,如下图所示。

image.png

z-index 负值深入理解

z-index 负值的最终表现并不是单一的,而是与“层叠上下文”和“层叠顺序”密切相关。z-index 负值渲染的过程就是一个寻找第一个层叠上下文 元素的过程,然后层叠顺序止步于这个层叠上下文元素。 明白了这一点,就可以理解为何 z-index 负值隐藏元素有时候确实隐藏,但有时候又隐藏不掉了。
那 z-index 负值的作用:

  • 可访问性隐藏。z-index 负值可以隐藏元素,只需要层叠上下文内的某一个父元素加个背景色就可以。
  • IE8 下的多背景模拟。
  • 定位在元素的后面。

z-index“不犯二”准则

对于非浮层元素,避免设置 z-index 值,z-index 值没有任何道理需要超过 2。
先讲一下为什么需要这个准则。

  • 定位元素一旦设置了 z-index 值,就从普通定位元素变成了层叠上下文元素,相互 间的层叠顺序就发生了根本的变化,很容易出现设置了巨大的 z-index 值也无法覆盖其他素的问题。
  • 避免 z-index“一山比一山高”的样式混乱问题。此问题多发生在多人协作以及后期维护的时候。

这里的“不犯二”准则,并不包括那些在页面上飘来飘去的元素定位, 弹框、出错提示、一些下拉效果等都不受这一准则限制。遵循“不犯二”准则的情况下,9 已经是个足够安全的值 了,浮层组件根本无须担心会被页面上某个元素层级覆盖。

参考

【1】CSS 世界@张鑫旭