CSS 零基础教程

CSS z-index 属性

CSS 中的 z-index 属性用于控制网页上重叠元素的堆叠顺序。

如果没有 z-index,元素在 HTML 中出现的顺序决定了谁在上面。然而,z-index 允许你显式定义堆叠顺序,而不管 HTML 结构如何。

理解 z-index 对于创建复杂布局、处理重叠元素以及确保元素按预期显示(尤其是在使用 absolutefixed 定位时)是必不可少的。它有助于管理元素的视觉层次结构,确保重要内容不被遮挡,且交互元素易于访问。

1. 理解 z-index 属性

z-index 属性指定了一个元素在其堆叠上下文 (Stacking Context) 中的堆叠层级。堆叠上下文是 HTML 元素沿假想的 Z 轴(相对于观察者)的三维概念,代表了优先级的层级。简单来说,z-index 决定了当元素重叠时,谁在前面,谁在后面。

1.1 z-index 的基础

  • z-index 接受整数值(正数、负数和 0)以及 auto
  • 默认值z-index 的默认值是 auto
  • 适用性z-index 仅对已定位元素有效(即 position 值为 relative, absolute, fixed, 或 sticky 的元素)。如果你试图将其应用于默认的 static 定位元素,它将没有任何效果。
  • 堆叠顺序:具有较高 z-index 值的元素将显示在具有较低 z-index 值的元素前面。
  • 上下文很重要:元素的 z-index 仅在其堆叠上下文内有意义。这意味着一个元素的 z-index 仅与同一堆叠上下文中的其他元素进行比较。

2. 堆叠上下文 (Stacking Contexts) 详解

堆叠上下文通过以下方式之一形成:

  1. 根元素 (<html>):这是整个文档的基础堆叠上下文。
  2. 已定位元素且 z-index 不为 auto:即 position 不为 static 且 z-index 设置了具体数值的元素。这是创建新堆叠上下文最常见的情况。
  3. 具有特定 CSS 属性的元素:某些 CSS 属性即使没有显式的 z-index 也会创建新的堆叠上下文,例如:
    • opacity 小于 1
    • transformfilterperspective 不为 none
    • isolation: isolate
    • mix-blend-mode 不为 normal
    • will-change 指定了上述任何属性

z-index: auto 的行为:当一个元素的 positionrelative/absolute/fixedz-indexauto 时,它不会创建新的堆叠上下文。它参与其父级的堆叠上下文。

3. z-index 与兄弟元素

当元素是兄弟元素(共享同一个父级)且属于同一个堆叠上下文时:

  1. 较高 z-index 胜出z-index: 2 的元素会显示在 z-index: 1 的元素之上。
  2. z-index 相同看源码顺序:如果两个兄弟元素具有相同的 z-index 值(或都是 auto),在 HTML 源代码中靠后出现的元素将堆叠在上面。这是默认的自然堆叠行为。

4. 实战示例

4.1 示例 1:z-index 的基本用法

考虑以下 HTML:

<div class="container">
  <div class="box box1">Box 1</div>
  <div class="box box2">Box 2</div>
</div>

CSS:

.container {
  position: relative; /* 创建层叠上下文 */
  width: 200px;
  height: 200px;
}
.box {
  position: absolute;
  width: 100px;
  height: 100px;
}
.box1 {
  background-color: rgba(255, 0, 0, 0.5); /* 红色,50% 透明度 */
  top: 20px;
  left: 20px;
  z-index: 1;
}
.box2 {
  background-color: rgba(0, 0, 255, 0.5); /* 蓝色,50% 透明度 */
  top: 40px;
  left: 40px;
  z-index: 2;
}

解析:
在这个例子中,.container 建立了层叠上下文,因为它具有 position: relative.box1.box2 在容器内绝对定位。因为 .box2 的 z-index (2) 高于 .box1 (1),所以 .box2(蓝色盒子)将显示在 .box1(红色盒子)的上方

4.2 示例 2:负值 z-index

你可以使用负的 z-index 值将元素放置在其父元素的后面。让我们修改前面的例子:

.container {
  position: relative;
  width: 200px;
  height: 200px;
  background-color: yellow; /* 添加背景色以便观察 */
}
.box {
  position: absolute;
  width: 100px;
  height: 100px;
}
.box1 {
  background-color: rgba(255, 0, 0, 0.5);
  top: 20px;
  left: 20px;
  z-index: -1; /* 负的 z-index */
}
.box2 {
  background-color: rgba(0, 0, 255, 0.5);
  top: 40px;
  left: 40px;
  z-index: 2;
}

解析:
现在,.box1 拥有 z-index: -1。这意味着它将被定位在 .container 元素本身的后面,当然也在 .box2 的后面。红色盒子将出现在容器的黄色背景后面。如果容器没有背景颜色,红色盒子实际上会看起来像是“消失”了(或者被放置在更下层的背景上)。

4.3 示例 3:层叠上下文与嵌套元素

层叠上下文是可以嵌套的。让我们看一个更复杂的场景:

<div class="container">
  <div class="box box1">Box 1</div>
  <div class="box box2">
    Box 2
    <div class="inner-box">Inner Box</div>
  </div>
</div>
.container {
  position: relative;
  width: 200px;
  height: 200px;
}
.box {
  position: absolute;
  width: 100px;
  height: 100px;
}
.box1 {
  background-color: rgba(255, 0, 0, 0.5);
  top: 20px;
  left: 20px;
  z-index: 1;
}
.box2 {
  background-color: rgba(0, 0, 255, 0.5);
  top: 40px;
  left: 40px;
  z-index: 2;
}
.inner-box {
  position: relative; /* 创建层叠上下文 */
  background-color: rgba(0, 255, 0, 0.5);
  width: 50px;
  height: 50px;
  top: 25px;
  left: 25px;
  z-index: 3;
}

解析:
在这里,.box2z-index 高于 .box1,所以它在上方。

然而,.inner-box 位于 .box2 内部,并且具有 position: relativez-index: 3
.inner-box 上的 position: relative.box2 内部创建了一个新的层叠上下文。.inner-box 上的 z-index: 3 仅在 .box2 的层叠上下文内部有效。

不会影响 .box1.box2 彼此之间的层叠顺序。内部盒子会位于 .box2 内部任何其他内容的上方,但 .box2 本身仍然保持在 .box1 的上方。