HTML 伪元素放置在实际子节点上

HTML pseudo elements placed over actual child nodes

由于某种原因,当一个元素的伪子节点被添加时,它的z-index高于它的子节点,即使它是一个::before元素,它出现在相对子节点之前,但没有' 那样显示。为什么会发生这种情况,有没有办法解决它?

这是一个示例,其中子 <h1> 节点 应该 看起来好像悬停在黑色伪元素上,但事实并非如此。

https://jsfiddle.net/9u33vko0/

我的理解根本就错了吗?

div {
  width: 100%;
  padding: 40px 0;
  border: 1px solid #DDD;
  text-align: center;
  color: #FFF;
  position: relative;
}

div::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  height: 100%;
  background-color: #000;
  width: 100%;
}
<div>
  <h1> <!-- should appear above the black ::before element -->
    Hello, World!
  </h1>
</div>

即使 :before 伪元素出现在 之前 DOM 中的 h1 元素,它仍然会与 h1 元素,因为它 establishes a stacking context 因为它被定位(使用 position: absolute)。

这是来自 CSS2 specification on stacking contexts(绘画顺序;第 8 点)

的相关引用

All positioned descendants with z-index: auto or z-index: 0, in tree order. For those with z-index: auto, treat the element as if it created a new stacking context ...

因此,您可以通过定位 h1 元素(即添加 position: relative)来建立一个堆叠上下文。这样做时,h1 元素将放置在 :before 伪元素上方,因为它出现在 DOM 中的伪元素之后,并且两个元素都使用 z-index 定位auto.

Updated Example

h1 {
  position: relative;
}

div {
  width: 100%;
  padding: 40px 0;
  border: 1px solid #DDD;
  text-align: center;
  color: #FFF;
  position: relative;
}

div::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  height: 100%;
  background-color: #000;
  width: 100%;
}

h1 {
  position: relative;
}
<div>
  <h1>Hello, World!</h1>
</div>

当然,你也可以只给伪元素一个负数z-index,但这不是重点。归根结底,建立堆栈上下文就足够了,因为 :before 伪元素出现在 DOM 中的 h1 元素之前(正如您已经指出的那样)。