当静态定位时,:: 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>
答案 0 :(得分:30)
div
的内容(包括两个伪元素和p
元素)参与相同的堆叠上下文(相对于div
)。这是因为,正如你所注意到的,它们中的三个都是静态定位的;换句话说,根本没有定位。 (是的,这些元素在流动时沿着z轴堆叠;你根本无法使用z-index
来操纵它们的堆栈级别,因为它们没有定位。)
Here's a summary 1 绘制各个部分的顺序,粗体强调与您的问题相关:
每个框属于一个堆叠上下文。给定堆叠上下文中的每个定位框都具有整数堆栈级别,这是它在z轴上相对于同一堆叠上下文中的其他堆栈级别的位置。具有更高堆栈级别的盒子总是在具有较低堆栈级别的盒子前面格式化。框可能具有负的堆栈级别。 堆叠上下文中具有相同堆栈级别的框根据文档树顺序从前到后堆叠。
在每个堆叠上下文中,以下按顺序绘制以下图层:
- 构成堆叠环境的元素的背景和边框。
- 子堆叠上下文具有负堆栈级别(最多为负数)。
- 流入的,非内联级别,未定位的后代。
- 未定位的花车。
- 流入的,内联级别的非定位后代,包括内联表和内联块。
- 堆叠级别为0的子堆叠上下文和堆栈级别为0的已定位后代。
- 具有正堆栈级别的子堆叠上下文(最少积极的第一个)。
醇>
由于在div::before
的内容之前插入div
,并且在div::after
之后插入p
,当它们以静态位置显示内联时,它们自然会遵循此规则,甚至如果将块元素夹在中间(排序会同时考虑块框和内联框)。
请注意,出于显而易见的原因,背景通常首先被绘制,内容覆盖它们:
p
元素作为块级元素,具有首先绘制的背景(#3)。
然后在p
背景(#5)上绘制内嵌级伪元素及其背景。在格式化模型中,它们是div
元素的兄弟,因此它们都参与p
的堆叠上下文而不是div::before
的堆叠上下文。
p
伪元素(其内容和背景)显示在p
文本后面,因为它位于可视树中的div::after
之前。
p
伪元素(其内容和背景)显示在p
文本的前面,因为它位于可视树中的div::before
之后。
正如我的评论if you make the pseudo-elements display as blocks所示,p
的背景将隐藏在div::before
元素的背后,而不是文本;相反,p
的文本将位于背景和div::after
元素的文本之间。另请注意,p
的背景绘制在{{1}}的背景之前,而内容则绘制在最前面。同样,这与在上述规则相关的内容之前或之后绘制的背景有关。
1 可以在规范的Appendix E中找到更详细的说明。