🚀 浏览器是怎样判断元素是否和某个CSS选择器匹配?

📅 发布于 2025年12月 | 👤 作者:博主 | 🏷️ 标签:"CSS引擎","优化", Web开发, 前端, 面试

欢迎来到我的博客文章!所有文章都是满满的前端干货,文章简明扼要。

总结

现代 CSS 引擎(如 Gecko、Blink)中样式匹配(Style Matching / Selector Matching)优化的两个核心思想:从右向左匹配 + 基于规则驱动的集合筛选。

浏览器先产生一个元素集合,这个集合往往由最后一个部分的索引产生(如果没有索引就是所有元素的集合)。然后向上匹配,如果不符合上一个部分,就把元素从集合中删除,直到真个选择器都匹配完,还在集合中的元素就匹配这个选择器了。

举例:

有选择器: div.ready #wrapper > .bg-red
先把所有元素 class 中有 bg-red 的元素拿出来组成一个集合,
然后上一层,对每一个集合中的元素,如果元素的parent id 不为 #wrapper 则把元素从集合中删去。
再向上,从这个元素的父元素开始向上找,没有找到一个 tagName 为 div 且class 中有 ready 的元素,就把原来的元素从集合中删去。
至此这个选择器匹配结束,所有还在集合中的元素满足。大体就是这样,不过浏览器还会有一些奇怪的优化。

注意:

  1. 为什么从后往前匹配因为效率和文档流的解析方向:效率不必说,找元素的父亲和之前的兄弟比遍历所有儿子快而且方便。关于文档流的解析方向,是因为现在的 CSS,一个元素只要确定了这个元素在文档流之前出现过的所有元素,就能确定他的匹配情况;应用在即使 html 没有载入完成,浏览器也能根据已经载入的这一部分信息完全确定出现过的元素的属性。
  2. 为什么是用集合主要也还是效率:基于 CSS Rule 数量远远小于元素数量的假设和索引的运用,遍历每一条 CSS Rule 通过集合筛选,比遍历每一个元素再遍历每一条 Rule 匹配要快得多。
← 返回首页