为什么文本节点默认呈现在其父级 ::before 下方?

Why is a textnode rendered below its parents` ::before by default?

在写关于 SO 的另一个问题的答案时,我制作了这个片段:

@import url('https://fonts.googleapis.com/css?family=Shadows+Into+Light');

/* relevant CSS */
div {
  position: relative;
}

div::before {
  content: '';
  position: absolute;
  top: 0; left:0;
}
div>span {
  position:relative;
  z-index:0;
}

/* rest is just styling - should be irrelevant for the question */


div {
  font: normal normal normal 2rem/1 'Shadows Into Light', cursive;
  color: white;
  text-align:center;
  margin: 1rem;
  padding: 1rem;
  min-width: 15rem;
  cursor: pointer;
}
div::before {
  width: 100%;
  height: 100%;
  opacity: 1;
  transition: opacity .3s cubic-bezier(.4,0,.2,1);
  background-color: #bada55;
  border-radius: .4rem;
}
div[orange]:before {
  background-color: #f50;
}
div:hover::before {
  opacity:.65;
}

body {
  margin: 0; padding: 0;
}
center-me-please {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  min-height: 100vh;
  background: transparent url(http://lorempixel.com/g/1200/800/fashion) no-repeat 50% 50% /cover;
}
<center-me-please>
  
  <div><span>#bada55</span></div>
  <div orange>not so #bada55</div>

我很惊讶地注意到 ::before 元素呈现在文本节点(橙色元素)上方,以防止它发生。我不得不将文本节点包装在一个 span 元素中,并给它一个非负 z-index 和一个非静态 position (#bada55 元素)。

经检查,虽然 ::before 元素的默认(预期)值为 z-index (auto),但文本节点似乎根本没有(或至少 Chrome 无法显示它)。

到目前为止,我喜欢把自己想象成一个 z-index 小忍者,这个想法在一定程度上得到了发展 this toy 的支持,以帮助朋友和同事更好地理解堆叠上下文原理和 z-index 一般。

正如您可能已经猜到的那样,我正在寻找关于为什么 ::before 默认情况下没有呈现在元素中其他所有内容下方的任何解释(它是第一个,因此在下方,对吗?)以及任何证据关于这是一个(已知?)错误或有意(按设计?)行为。

我可能错过或误解的规范会很棒。

::before 默认情况下在文本内容下方绘制 — 默认情况是 everything is non-positioned.

但是你的::before是绝对定位的。定位框总是绘制在 non-positioned 个框的前面。参考section 9.9.1(强调我的):

Within each stacking context, the following layers are painted in back-to-front order:

  1. the background and borders of the element forming the stacking context.
  2. the child stacking contexts with negative stack levels (most negative first).
  3. the in-flow, non-inline-level, non-positioned descendants.
  4. the non-positioned floats.
  5. the in-flow, inline-level, non-positioned descendants, including inline tables and inline blocks.
  6. the child stacking contexts with stack level 0 and the positioned descendants with stack level 0.
  7. the child stacking contexts with positive stack levels (least positive first).

将您的文本内容包装在定位的 span 中会导致它按预期绘制在 ::before 内容的前面,此后您在源代码顺序中有两个定位框。