为什么伪内容:after 不是显示在after 而是在相应的div 中?

Why is the pseudo content :after not shown after but in the corresponding div?

以下示例显示了 box div:after 内容,这应该是一个单独的块。

div.box {
    background-color: #FAA;
    width: 10em;
    overflow: scroll;
}
div.box:after {
    content: "☑";
    display: block;
    background-color: #AFA;
    width: 5em;
    overflow: auto;
}
<div class="box">x</div>

但是后面的内容是放在滚动条里面的。我的期望是它实际上出现在可滚动区域之后。

:after 内容位于可滚动区域内,因为即使该元素被命名为 :after,它实际上是 div.box 的子元素,因此将位于.box 元素(在可滚动区域内)。

From MDN: The CSS ::after pseudo-element matches a virtual last child of the selected element.

(强调我的)

因此,有问题的代码本质上与以下代码段相同。

div.box {
    background-color: #FAA;
    width: 10em;
    overflow: scroll;
}
div.box .after {
    display: block;
    background-color: #AFA;
    width: 5em;
    overflow: auto;
}
<div class="box">x
  <div class="after">☑</div>
</div>


如果您希望它位于 div.box 之外,那么您必须在容器上使用 :after(或)使用绝对定位。

div.box {
    background-color: #FAA;
    width: 10em;
    overflow: scroll;
}
div.container:after {
    content: "☑";
    display: block;
    background-color: #AFA;
    width: 5em;
    overflow: auto;
}
<div class="container">
  <div class="box">x</div>
</div>

我认为你对伪元素有点困惑,所以我希望能为你澄清一些事情:

The ::after pseudo-element can be used to describe generated content after an element's content.

对此的快速演示是:

 p::after {
   content: "  :Note";
 }
<p>In CSS 2.1, it is not possible to refer to attribute values for other elements than the subject of the selector.</p>

看看如何,无论 div 在哪里,伪元素都将显示在它所附加的元素之后。这是为添加内容 before 或添加内容 after.

设计的伪元素的方式

这意味着:after相对于'real'元素定位,不是出现在'scrollbars'.

之后

相反,如果您绝对 定位伪元素 ,那么正如您期望定位子元素一样,您可以 'move' 它使用 leftrighttopbottom 属性:

div.box {
    background-color: #FAA;
    width: 10em;
    overflow: scroll;
}
div.box:after {
    content: "☑";
    position:absolute;
    display: block;
    background-color: #AFA;
    width: 5em;
    overflow: auto;
}
<div class="box">x</div>

备注

但是,我会将可滚动内容包装在 div 中,这样您就可以更好地控制元素的定位。


::after:after

的相似之处

This [double-colon] notation is introduced … in order to establish a discrimination between pseudo-classes and pseudo-elements. For compatibility with existing style sheets, user agents must also accept the previous one-colon notation for pseudo-elements introduced in CSS levels 1 and 2 (namely, :first-line, :first-letter, :before and :after). This compatibility is not allowed for the new pseudo-elements introduced in CSS level 3. ~Spec

所以,简短的回答是..

两种写法没有区别

略长的答案是...

随着CSS3的引入,为了区分伪类和伪元素,在CSS3中所有的伪元素都必须使用双冒号语法 (::after),所有伪 类 必须使用单冒号语法 (:first-child).

然而,由于 IE8 及以下版本不理解此 'double colon' 语法(以及许多其他语法),浏览器无论如何都会接受单冒号语法(允许 IE 8 及以下版本也理解它)。这就是为什么开发人员在广泛的方面选择继续使用单冒号语法以便 IE8(及更低版本)理解,从而使您的网站具有更好的浏览器兼容性。


进一步阅读

My expectation was that it comes actually after the scrollable area.

这个预期是错误的。查看 CSS2.1 规范,我们发现:

Authors specify the style and location of generated content with the :before and :after pseudo-elements. As their names indicate, the :before and :after pseudo-elements specify the location of content before and after an element's document tree content.

然后:

The formatting objects (e.g., boxes) generated by an element include generated content.

这意味着您使用 div.box:after 规则添加的内容包含在 div 中。 "after"是指放在div的正常内容[=24=之后],而不是放在整个div.

之后

来源:http://www.w3.org/TR/CSS21/generate.html