浏览器如何渲染伪元素选择器?

3

我特别想知道的是,使用 *:after 会不会在资源方面比较昂贵。在这种情况下,伪元素会成为关键选择器吗?还是客户端会抓取所有元素?

换句话说,使用 *:after* 有什么性能上的区别吗?


[编辑。愚蠢的例子。我的错。]

为了澄清,我正在尝试只使用 CSS 绘制一些东西,并发现自己正在大量使用伪元素。只是想知道是否可以通过编写 ... 来节省时间。

*:after, 
*:before {
   content:'';
}

以及它的资源成本。

谢谢。


即使你编辑了,我仍然不明白你尝试在 *:after 中做什么。 - Mr. Alien
1
@Mr. Alien:我认为他正在询问比较样式化实际元素和伪元素的效果,此时选择器主题并不太相关。 - BoltClock
@BoltClock现在有一个清晰的场景,我只需要编辑我的答案。 - Mr. Alien
@BoltClock和我意识到,我给了他同样的建议:p使用.container * - Mr. Alien
2个回答

4
在这种情况下,伪元素是否会成为关键选择器?
从技术上讲,选择器的“主题”是“*”,这意味着与“*”匹配的任何元素都将生成伪元素。
当涉及到伪元素时,“关键选择器”一词没有明确定义,而且与主题选择器的概念不同,它实际上是一个实现细节。如果“关键选择器”意味着“表示呈现的框的选择器”,那么我想你可以说伪元素是关键选择器。不过,我不熟悉实现细节,因为我不是实现者。
无论如何,可以安全地假定客户端遍历DOM,并针对其挑选出的每个元素执行以下操作:
1. 尝试匹配该元素与选择器(在这种情况下是“*”),暂时忽略伪元素。 2. 如果元素与选择器匹配,则尝试作为该元素框的子级创建伪元素框(对于生成的伪元素,如:before和:after)(某些元素无法生成伪元素)。 3. 对伪元素框应用样式并像其他框一样呈现它。
您两个选择器之间的差异在于前者包含一个伪元素,而后者则不包含。由于它们执行的功能完全不同,因此按性能进行比较是不公平的。但是,它们都尝试匹配DOM中的任何元素,因为它们都使用相同的万能选择器“*”,因此除非有任何特殊优化,否则可以安全地假定仅与“*:after”相关的额外开销在于生成和呈现伪元素本身。
既然我们正在讨论性能问题,请记住,将元素与“*”匹配几乎是瞬间完成的,因为它基本上是一个保证的匹配;仅当您将其与更复杂的选择器组合时,它才会在选择器级别上变得更加昂贵,并且虽然最终性能随着DOM中的元素数量而增加,但它仍不像实际呈现样式那样昂贵,除非您有成千上万的元素。
至于您的用例,我的意见是通常情况下不需要为每个元素创建伪元素。如果您正在使用CSS绘制某些内容,请尝试通过上下文限制您的选择器,以避免在整个DOM中呈现不必要的框,例如,如果您只在具有特定ID的元素中绘制:
#mycanvas *:after, 
#mycanvas *:before {
   content:'';
}

3

问题编辑后

我现在对你想要问什么有了明确的了解,当你使用*时,它会选择所有元素,但这样不够精确。如果你想,你可以使用类似于以下的内容:

.container *:not(span) {
   color: red;
}

或者(但下面这个将选择所有嵌套在.container内的元素)
.container * {
   color: red;
}

演示


在问题编辑前

我不太明白你在问什么,但是这两个选择器是完全不同的。它们用于不同的目的。我不知道你的问题是否有笔误,但使用*:after通常与必须嵌入:before:aftercontent一起使用。

例如:

*:after {
    content: " <";
}

演示

当您使用这个方法时,* .after 会选择具有 .after 类的元素。

* .after {
    color: red;
}

演示2


就优化而言,我认为在一般网站中使用*并不是一个很大的性能问题,我经常使用以下选择器来保存属性:

* {
   margin: 0;
   padding: 0;
   -moz-box-sizing: border-box;
   -webkit-box-sizing: border-box;
   box-sizing: border-box;
}

此外,最后但并非最不重要的一点是,我认为没有理由使用*:after,因为您不会为每个元素使用:after来嵌入某些内容。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接