:: before伪元素堆叠顺序问题 [英] ::before pseudo-element stacking order issue

查看:120
本文介绍了:: before伪元素堆叠顺序问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当静态定位时,:: 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;颜色:白色; 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/

解决方案

div 包括两个伪元素和 p 元素,参与相同的堆栈上下文(相对于 div )。这是因为,你注意到,他们三个都是静态定位;换句话说,根本不定位。 (是的,这些元素在流程中沿z轴堆叠;你根本不能使用 z-index 来操纵它们的堆栈级别,因为它们没有定位。)

这是摘要 1 各种部分的绘制顺序,与您的问题相关的粗体重点:


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



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


  1. 形成堆叠上下文的元素的背景和边框。




  2. 在线,内联级,非定位后代。

  3. 子级堆栈上下文与堆栈级别0和定位的后代与堆栈级别0。
  4. >
  5. 子堆栈上下文具有正堆栈级别(最小为正)。


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



请注意,原因,背景通常先绘制,内容覆盖它们:


  1. p 元素作为块级元素,具有第一个绘​​制的背景(#3)。


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


  3. div :: before 伪元素(其内容和背景)出现在 p 文本后面,因为它在 p 在视觉树中。


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


如我在评论中所述,如果你使伪元素显示为块 div :: before 的背景将隐藏在 p 元素,但不是文本;相反, div :: before 的文本将位于背景和 p 元素的文本之间。还要注意 div :: after 的背景是在 p 的前面绘制的,是最前面。同样,这与在上述规则的内容之前或之后绘制的背景有关。






< sup> 1 有关更详细的说明,请参阅附录E 规格


When statically positioned, the ::before pseudo-element stacks (z-index) before the child's content, but after the child's background. Can anyone explain why or even how this is happening or if this is an issue that all major browsers have?

<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/

解决方案

The contents of the div, which include the two pseudo-elements and the p element, participate in the same stacking context (relative to the div). This is because, as you note, all three of them are statically-positioned; in other words, not positioned at all. (Yes, these elements do stack along the z-axis while in flow; you simply cannot manipulate their stack levels using z-index because they're not positioned.)

Here's a summary1 of the order in which the various parts are drawn, bold emphases where relevant to your question:

Each box belongs to one stacking context. Each positioned box in a given stacking context has an integer stack level, which is its position on the z-axis relative other stack levels within the same stacking context. Boxes with greater stack levels are always formatted in front of boxes with lower stack levels. Boxes may have negative stack levels. Boxes with the same stack level in a stacking context are stacked back-to-front according to document tree order.

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).

Since div::before is inserted before the content of the div, and div::after is inserted after it, when they display inline in a static position they'll naturally follow this rule, even if sandwiching a block element (the ordering takes both block boxes and inline boxes into account).

Notice that, for obvious reasons, backgrounds are usually painted first, with the content overlaying them:

  1. The p element, as a block-level element, has a background that's painted first (#3).

  2. The inline-level pseudo-elements are then drawn with their backgrounds over the p background (#5). In the formatting model, they are siblings of the p element, so they all participate in the stacking context of the div and not that of the p.

  3. The div::before pseudo-element (both its content and background) appears behind the p text because it comes before the p in the visual tree.

  4. The div::after pseudo-element (both its content and background) appears in front of the p text because it comes after the p in the visual tree.

As indicated in my comment, if you make the pseudo-elements display as blocks, the background of the div::before will hide behind that of the p element, but not the text; instead, the text of the div::before will be positioned between the background and the text of the p element. Also notice that the background of the div::after is painted in front of that of the p, while the content is painted frontmost. Again, this has to do with backgrounds being painted before, or behind, content in relation to the rules above.


1 A much more detailed description can be found in Appendix E of the spec.

这篇关于:: before伪元素堆叠顺序问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆