【问题标题】:How does the browser render pseudo element selectors?浏览器如何渲染伪元素选择器?
【发布时间】:2013-09-03 08:07:42
【问题描述】:

我特别想知道的是,*:after 在资源方面会有多贵。 在这种情况下,伪元素会成为键选择器吗?还是客户端无论如何都会抓取所有元素?

换句话说,*:after* 在性能方面有什么区别?


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

为了澄清起见,我正在尝试仅使用 css 进行绘制,发现自己使用了很多伪元素。如果我可以通过写作来节省一些时间,那就徘徊

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

及其资源成本。

谢谢。

【问题讨论】:

  • 即使在你编辑之后,我仍然没有得到你想要用*:after做的事情
  • @Mr. Alien:我认为他是在询问比较实际元素样式与伪元素样式的效果,在这种情况下,选择器主题不太相关。
  • @BoltClock 现在有一个清晰的场景,只需编辑我的答案
  • @BoltClock 我意识到我给了他同样的建议:p 使用.container *

标签: css css-selectors pseudo-element css-content


【解决方案1】:

在这种情况下,伪元素会成为键选择器吗?

从技术上讲,选择器的主题*,这意味着与*匹配的任何元素都会生成伪元素。

当涉及到伪元素时,术语“键选择器”的定义并不明确,而且与主题选择器的概念不同,它实际上是一个实现细节。如果“键选择器”的意思是“代表被渲染的框的选择器”,那么我想你可以说伪元素是键选择器。不过,我不熟悉实现细节,因为我不是实现者。

无论哪种方式,都可以安全地假设客户端遍历 DOM,并且对于它挑选出的每个元素:

  1. 尝试将元素与选择器进行匹配,暂时忽略伪元素(在本例中为*)。

  2. 如果元素与选择器匹配,则尝试创建一个伪元素框作为该元素框的子元素(在生成的伪元素如:before:after 的情况下)如果适用(有些元素不能生成伪元素)。

  3. 将样式应用于伪元素框并将其渲染为与任何其他框一样。

您的两个选择器之间的区别在于前者包含伪元素,而后者不包含。由于它们做的事情根本不同,因此按性能比较它们是不公平的。但是,它们都确实尝试匹配 DOM 中的任何元素,因为它们都使用相同的包罗万象的选择器 *,因此除非进行任何特殊优化,否则可以安全地假设唯一的开销是*:after 在于实际生成和渲染伪元素。

由于我们讨论的是性能,请记住将元素与* 匹配几乎是瞬时的,因为它基本上是有保证的匹配;只有当你将它与更复杂的选择器结合使用时,它才会在选择器级别上变得更加昂贵,虽然最终它的性能随着你在 DOM 中拥有的元素数量而增长最大,但它仍然没有实际渲染样式那么昂贵除非你有成千上万的元素。


至于您的用例,我认为您通常不需要为每个元素创建伪元素。如果您使用 CSS 绘制某些内容,请查看是否可以通过上下文限制选择器,以避免在整个 DOM 中呈现不必要的框,例如如果您只在具有特定 ID 的元素内绘图:

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

【讨论】:

    【解决方案2】:

    问题编辑后

    刚刚清楚地了解了您要在此处询问的内容,因此当您使用* 时,无论如何它都会选择元素,但这并不精确,因为它会选择所有元素.. 如果您想要,你可以使用类似的东西

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

    或者(但下面的会选择嵌套在.container中的所有元素)

    .container * {
       color: red;
    }
    

    Demo


    问题编辑前

    我无法理解您在这里问什么,但是两个选择器完全不同..它们用于不同的目的,我不知道这是否是您的问题中的错字,但使用*:after 经常与content 一起使用,必须嵌入:before:after

    所以,例如

    *:after {
        content: " <";
    }
    

    Demo

    当您使用它时,* .after 将选择具有类 .after 的元素

    * .after {
        color: red;
    }
    

    Demo 2


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

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

    另外,最后但并非最不重要的一点是,我找不到任何理由使用 *:after,因为您不会为每个元素使用 :after 嵌入一些内容。

    【讨论】:

      猜你喜欢
      • 2023-03-13
      • 2012-09-13
      • 1970-01-01
      • 2013-10-11
      • 2017-11-28
      • 2011-08-02
      • 1970-01-01
      • 2012-10-19
      • 2017-06-07
      相关资源
      最近更新 更多