在 HTML 中,::after 和 ::before 伪元素是否只适用于可渲染的 "non-replaced" 元素?

In HTML, do ::after and ::before pseudoelements only work with renderable "non-replaced" elements?

我最近在一个项目中注意到::after伪元素在input元素之后没有添加任何内容:

input::after { content: "xxxxxxxxxx"; } // no "virtual last child" inserted into DOM "after" the input

(对 "virtual last child" 的引用来自 MDN 页面 here

当然,一个元素比如adiv会有内容"after"它,而最后的child“::after”会被插入到DOM:

div:empty::after { content: "xxxxxxxxxx"; }

//In DOM
<div>::after</div>

但在这些情况下没有插入任何内容:

head, script { content: "qaqaqa"; }

我最初的假设是浏览器呈现的任何 HTML 元素都带有应该关闭的标签(例如,p、body、html、div。 ...etc) 将 ::after 作为最后一个 child 插入(并且 ::before 作为 first-child 插入),而不适合这个的元素(例如,脚本, head, img, br, input,...etc) 不会表现出这种行为。我的 CodePen 尝试表明这是正确的。

我通读了文档,最终找到了 this resource,其中有一条注释:

 Note. This specification does not fully define the interaction 
       of :before and :after with replaced elements (such as IMG in HTML). 
       This will be defined in more detail in a future specification.

(有关 "replaced elements" 的定义,请参阅 here

所以现在我对 ::after::before 改进假设 是这些伪元素仅适用于无法分类的 "renderable" 元素作为 "replaced elements"(请注意,这个改进的假设现在排除 textarea::after / ::before 一起使用,而我的初始假设将 包括 它 - textarea::after 使用 CodePen 进行了测试,没有 ::after 最后 child 插入到 DOM).

完善的假设是否正确?

不要猜测,阅读:https://drafts.csswg.org/selectors-3/#gen-content

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

input 没有内容,所以没有显示 after 元素。这同样适用于每个没有内容的 HTML 元素(brmenuitemlink...)。所有自动关闭标签都没有内容,其他一些(如 script)也有 none。

HTML没有定义哪些元素是替换元素或者哪些元素可以包含::before::after伪元素。 CSS2.1 或 selectors-3 也不行。然而,css-content-3 的最新重写非常明确:

Replaced elements do not have '::before' and '::after' pseudo-elements

虽然实现当然与草案不一致(著名或其他,WebKit/Blink),因为迄今为止还没有定义。

一个元素是否可以有 ::before::after 伪元素不是由它的内容模型定义的(即它是否为 void 或其他),或者它是否有一个结束标签,在 HTML。而且,其中很多都是依赖于实现的。例如,某些实现允许 br 的所有事物具有 ::before::after 伪元素,因为没有人确切知道 br 应该如何根据 CSS 并且每个浏览器都有自己的方式(因为 HTML 和 CSS 都没有真正定义它)。

A head 元素及其任何后代 can::before::after 伪元素——你所要做的就是将他们的 display 更改为 none 以外的内容。显然,它们不应该被显示出来,但这并不能阻止任何人想变聪明。

就CSS而言,inputtextarea都被认为是替换元素,即使textarea有开始标签、结束标签和内容.这些元素是否 shouldmust 没有说明(甚至在 section 14.5 of WHATWG HTML 中也没有),但大多数浏览器将它们呈现为替换元素默认情况下,此行为通常无法更改。为了不支持 ::before::after 伪元素,这才是最重要的。