【问题标题】:::before pseudo-element stacking order issue::在伪元素堆叠顺序问题之前
【发布时间】:2012-06-20 17:41:45
【问题描述】:

当静态定位时,::before 伪元素堆叠(z-index)在子元素的内容之前,但在子元素的背景之后。任何人都可以解释为什么甚至是如何发生这种情况,或者这是所有主要浏览器都存在的问题吗?

<style>
div { background-color:yellow; width:400px; }
div::before { background-color:red; content:"div::before"; }
div::after { background-color:green; content:"div::after"; }
div p { background-color:blue; color:white; margin:-15px 0; padding:0; }
</style>
<div>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam sed tellus sed tellus sodales hendrerit tristique et elit.</p>
</div>

http://jsfiddle.net/funkyscript/ALrgf/

【问题讨论】:

  • 如果将两个伪元素都显示为块,::before 背景会隐藏在p 背景后面:jsfiddle.net/BoltClock/cVzs8/1 注意它们默认显示为内联。
  • @BoltClock:这很奇怪,但是,从表面上看,这很有趣……这是一个错误,还是设计使然? (如果你有能力或有能力回答这个问题。)
  • 这不起作用,但它不应该有一个冒号吗? :before:after?
  • @Kobi:CSS3 中为伪元素引入了双冒号符号:w3.org/TR/selectors/#pseudo-elements
  • @David Thomas:你不认为我是 CSSWG 的成员,是吗? :O (我是多么希望...)

标签: css z-index pseudo-element


【解决方案1】:

div 的内容,包括两个伪元素和p 元素,参与相同的堆叠上下文(相对于div)。这是因为,正如您所注意到的,它们三个都是静态定位的。换句话说,根本没有定位。 (是的,这些元素在流动时会沿 z 轴堆叠;您根本无法使用 z-index 操作它们的堆叠级别,因为它们没有定位。)

Here's a summary1 各个部分的绘制顺序,在与您的问题相关的地方用粗体强调:

每个盒子都属于一个堆叠上下文。给定堆叠上下文中的每个定位框都有一个整数堆叠级别,这是它在 z 轴上相对于同一堆叠上下文中其他堆叠级别的位置。具有较高堆栈级别的框总是在具有较低堆栈级别的框之前格式化。盒子可能有负的堆栈级别。 堆叠上下文中具有相同堆叠级别的框根据文档树顺序从后到前堆叠。

在每个堆叠上下文中,以下图层按从后到前的顺序绘制:

  1. 构成堆叠上下文的元素的背景和边框。
  2. 具有负堆栈级别(最负优先)的子堆栈上下文。
  3. 流入、非内联级、非定位的后代。
  4. 未定位的浮动。
  5. 流入、内联级、非定位后代,包括内联表和内联块。
  6. 堆栈级别为 0 的子堆栈上下文和堆栈级别为 0 的定位后代。
  7. 具有正堆栈级别的子堆栈上下文(最不正的优先)。

由于div::before是在div的内容之前插入的,div::after是在它之后插入的,所以当它们在静态位置显示内联时,它们自然会遵循这个规则,即使夹着一个块元素(排序同时考虑了块框和内联框)。

请注意,出于显而易见的原因,通常先绘制背景,然后将内容覆盖在它们之上:

  1. p 元素作为块级元素,具有首先绘制的背景 (#3)。

  2. 然后将内联级伪元素的背景绘制在p 背景上(#5)。在格式化模型中,它们是p元素的兄弟,所以它们都参与div的堆叠上下文,而不是p的堆叠上下文。

  3. div::before 伪元素(包括其内容和背景)出现在 p 文本之后,因为它在可视化树中位于 p 之前。

  4. div::after 伪元素(其内容和背景)出现在 p 文本的前面,因为它在可视树中位于 p 之后。

正如我在if you make the pseudo-elements display as blocks 的评论中所指出的,div::before 的背景将隐藏在 p 元素的背景之后,而不是文本;相反,div::before 的文本将位于背景和p 元素的文本之间。还要注意div::after的背景画在p的前面,而内容画在最前面。同样,这与根据上述规则在内容之前或之后绘制背景有关。


1更详细的描述可以在规范的Appendix E 中找到。

【讨论】:

  • 几乎是有道理的——但是为什么:before在文本和内容的背景之间呢? (好吧,我想这回答了我的问题:P)。哎,这玩意比我想象的还要复杂……
  • 使用跨度而不是伪元素返回相同的结果。
  • 关于您在项目符号 2 上所说的内容:根据我从规范中了解到的情况,伪元素 pp 中的文本都将位于相同的堆叠上下文中( p 上没有 z-index+position - 或 opacity - 创建一个新的)。无论如何,我已经多次阅读您的答案(以及规格,包括Appendix E),试图回答this other question,但我未能完全理解问题的原因。也许你能帮忙?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-03
  • 1970-01-01
  • 2020-08-05
  • 2018-11-11
  • 1970-01-01
相关资源
最近更新 更多