CSS 选择器由浏览器引擎从右到左匹配。所以他们首先找到孩子,然后检查他们的父母,看看他们是否符合规则的其余部分。
对我来说,最简单的方法是使用元素数量最少的选择器。所以首先是 ID(因为它们应该只返回 1 个元素)。然后可能是具有最少节点数的类或元素 - 例如,页面上可能只有一个跨度,因此使用任何引用跨度的规则直接转到该节点。
这里有一些链接支持我的主张
听起来这样做是为了避免必须查看父母的所有孩子(可能很多),而不是必须是一个孩子的所有父母。即使 DOM 很深,它也只会在每个级别查看一个节点,而不是在 RTL 匹配中查看多个节点。
请记住,当浏览器进行选择器匹配时,它有一个元素(它试图为其确定样式的那个)和所有规则及其选择器,它需要找到哪些规则与该元素匹配。这与通常的 jQuery 不同,比如说,您只有一个选择器,并且您需要找到与该选择器匹配的所有元素。
如果您只有一个选择器并且只有一个元素可以与该选择器进行比较,那么在某些情况下从左到右更有意义。但这绝对 不是 浏览器的情况。浏览器正在尝试呈现 Gmail 或其他任何内容,并且拥有<span>它正在尝试设置样式的内容以及 Gmail 在其样式表中放置的 10,000 多个规则(我没有编造这个数字)。
<span>
特别是,在浏览器正在查看它正在考虑的大多数选择器与所讨论的元素 不 匹配的情况下。所以问题变成了决定选择器不能尽可能快地匹配的问题。如果在匹配的情况下需要做一些额外的工作,您仍然会赢,因为您在不匹配的情况下节省了所有工作。
如果您首先将选择器的最右边部分与您的元素进行匹配,那么它很可能不会匹配并且您已经完成了。如果它匹配,你必须做更多的工作,但只与你的树深度成正比,在大多数情况下并没有那么大。
另一方面,如果你从匹配选择器的最左边开始......你将它与什么匹配?你必须开始遍历 DOM,寻找可能匹配它的节点。只是发现没有匹配最左边的部分可能需要一段时间。
所以浏览器从右边匹配;它提供了一个明显的起点,让您可以非常快速地摆脱大多数候选选择器。您可以在http://groups.google.com/group/mozilla.dev.tech.layout/browse_thread/thread/b185e455a0b3562a/7db34de545c17665看到一些数据(尽管符号令人困惑),但结果是 Gmail 特别是两年前,对于 70% 的 (rule, element) 对,您只需检查规则最右侧选择器的 tag/class/id 部分就可以确定该规则不匹配。Mozilla 的页面加载性能测试套件的相应数字为 72%。因此,尽可能快地摆脱所有规则中的 2/3,然后只担心匹配剩余的 1/3 是非常值得的。
另请注意,浏览器已经进行了其他优化,以避免尝试匹配绝对不匹配的规则。例如,如果最右边的选择器有一个 id 并且该 id 与元素的 id 不匹配,那么在 Gecko 中将不会尝试将该选择器与该元素匹配:尝试的“具有 ID 的选择器”集合来自对元素 ID 的哈希表查找。所以这是 70% 的规则,在考虑到最右边选择器的标签/类/id 之后,它们有很大的匹配机会 仍然 不匹配。