Z-index 和堆叠上下文

CSS 播客 - 019:z-index 和堆叠上下文

假设您有几个绝对定位的元素,并且应该彼此堆叠。您可能会编写如下 HTML 代码

<div class="stacked-items">
    <div class="item-1">Item 1</div>
    <div class="item-2">Item 2</div>
</div>

但是默认情况下,哪个元素位于另一个元素的顶部?要了解哪个项目会这样做,您需要了解 z-index 和堆叠上下文。

Z-index

z-index 属性根据浏览器的 3D 空间(Z 轴)显式设置 HTML 的图层顺序。此轴显示哪些图层更靠近您,哪些图层离您更远。Web 上的垂直轴是 Y 轴,水平轴是 X 轴。

Each axis surrounding the element

z-index 属性接受一个数值,可以是正数或负数。如果元素的 z-index 值较高,则它们将显示在另一个元素的上方。如果您的元素上未设置 z-index,则默认行为是文档源顺序决定 Z 轴。这意味着文档中较靠下的元素位于出现在它们之前的元素的顶部。

在正常流中,如果您为 z-index 设置了特定值但它不起作用,则需要将元素的 position 值设置为除 static 之外的任何值。这是人们在使用 z-index 时经常遇到问题的地方。

但是,如果您处于 flexbox 或 grid 上下文中,则情况并非如此,因为您可以修改 flex 或 grid 项目的 z-index,而无需添加 position: relative

负 z-index

要将元素设置在另一个元素之后,请为 z-index 添加负值。

.my-element {
    background: rgb(232 240 254 / 0.4);
}

.my-element .child {
    position: relative;
    z-index: -1;
}

只要 .my-elementz-index 初始值为 auto.child 元素就会位于其后。

将以下 CSS 添加到 .my-element.child 元素将不会位于其后。

.my-element {
  position: relative;
  z-index: 0;
  background: rgb(232 240 254 / 0.4);
}

因为 .my-element 现在具有非 staticposition 值和非 autoz-index 值,所以它创建了一个新的堆叠上下文。这意味着即使您将 .childz-index 设置为 -999,它仍然不会位于 .my-parent 之后。

堆叠上下文

堆叠上下文是一组具有共同父元素并在 Z 轴上一起上下移动的元素。

在此示例中,第一个父元素的 z-index1,因此创建了一个新的堆叠上下文。其子元素的 z-index999。在此父元素旁边,还有另一个父元素,其中包含一个子元素。父元素的 z-index2,子元素的 z-index 也为 2。由于两个父元素都创建了堆叠上下文,因此所有子元素的 z-index 都基于其父元素的 z-index

堆叠上下文中元素的 z-index 始终相对于其父元素在其自身堆叠上下文中的当前顺序。

创建堆叠上下文

您不需要应用 z-indexposition 来创建新的堆叠上下文。您可以通过为创建新合成图层的属性(例如 opacitywill-changetransform)添加值来创建新的堆叠上下文。您可以在此处查看属性的完整列表

为了解释什么是合成图层,请将网页想象成一块画布。浏览器会获取您的 HTML 和 CSS,并使用它们来计算出画布的大小。然后,它会将页面绘制在这块画布上。如果元素发生更改(例如,更改位置),则浏览器必须返回并重新计算要绘制的内容。

为了帮助提高性能,浏览器会创建新的合成图层,这些图层层叠在画布之上。这些图层有点像便利贴:移动其中一个图层并更改它不会对整个画布产生巨大影响。对于具有 opacitytransformwill-change 的元素,会创建一个新的合成图层,因为这些元素很可能发生更改,因此浏览器会确保通过使用 GPU 应用样式调整来尽可能地提高更改的性能。

资源

检查您的理解

测试您对 z-index 的知识

<section>
  <article>1</article>
  <article>2</article>
  <article>3</article>
  <article>4</article>
</section>

默认情况下,哪篇文章位于顶部?

1
它在最底部。
2
再试一次!
3
再试一次!
4
文档中的最后一个位于顶部,是的!

如果 z-index 不起作用,您应该检查元素上的哪个属性?

display
不太可能是 display 属性导致 z-index 不起作用。
relative
这是一个 CSS 值,而不是属性。
position
确保将其设置为除 static 之外的其他值。
animation
不太可能是 display 属性导致 z-index 不起作用。

flexbox 和 grid 需要 position: relative 吗?

这些 display 类型不需要它。
在 flexbox 或 grid 布局中使用 z-index 将在没有 position: relative 的情况下工作。