CSS规范并没有明确浏览器如何去实现样式系统,仅仅是说明了它们必须这样做。有鉴于此,不同的样式系统引擎可能会拥有完全不同的表现和行为,特别是 Gecko 与 WebKit, 这两个引擎都是开源项目,实现了类似的算法,具有极其相近的优缺点。因此下面介绍的小技巧对于真实世界的 Web 文档将会十分有用。
第一部分内容综合讨论了常见的样式系统是如何分类规则的。接下来的部分包含了书写规则的指南,它利用了前面讨论的样式系统的优点。
样式系统如何拆分规则
样式系统将规则拆分成四个主要类别:
1.ID 规则
2.Class 规则
3.标签规则
4.通用规则
理解这些分类是十分关键的,因为它们是构建规则匹配块的基础。
我在下面的段落中使用术语 关键选择器(key selector)。选择器的最后面的部分即为关键选择器(即用来匹配目标元素的那部分,而不是该元素的祖先元素)。
例如,在下面规则中…
- a img,
- div > p,
- h1 + [title] {
- …
- }
关键选择器为 img、 p 和 title.
ID 规则
这第一个类别包含了那些将 ID 选择器作为关键选择器的规则。
示例
- button#backButton {…} /* This is an ID-categorized rule */
- #urlBar[type="autocomplete"] {…} /* This is an ID-categorized rule */
- treeitem > treerow > treecell#myCell:active {…} /* This is an ID-categorized rule */
Class 规则
如果一个规则将一个 class 明确作为它的关键选择器,那么它就属于该类别。
示例
- button.toolbarButton {…} /* A class-based rule */
- .fancyText {…} /* A class-based rule */
- menuitem > .menu-left[checked="true"] {…} /* A class-based rule */
标签规则
如果既没有 class 也没有 ID 来明确作为关键选择器,那么接下来的候选者就是 标签 类别。 如果一条规则将一个标签作为它的关键选择器,那么这条规则就属于该类别。
示例
- td {…} /* A tag-based rule */
- treeitem > treerow {…} /* A tag-based rule */
- input[type="checkbox"] {…} /* A tag-based rule */
通用规则
不属于上面那些类别的规则都属于这个类别。
示例
- [hidden="true"] {…} /* A universal rule */
- * {…} /* A universal rule */
- tree > [collapsed="true"] {…} /* A universal rule */
样式系统如何匹配规则
样式系统从关键选择器开始匹配规则,然后左移(查找规则选择器的任何祖先元素)。只要选择器的子树(substree)一直在检查,样式系统就会持续左移,直到和规则匹配,或者是因为不匹配而放弃该条规则。
规则过滤是你需要学习的最基础的概念。分类存在的意义就是过滤掉无关的规则(这样样式系统就不会浪费时间去匹配它们了)。
这就是能够极大提高性能的关键。对于一个给定的元素,需要匹配的规则越少,样式的解析就会越快。
举个例子,如果一个元素拥有一个 ID,那么只有匹配该 ID 的 ID 规则才会被选中。同理,只有当 Class 规则中的 class 出现在元素上时该规则才被检查。只有当标签规则的标签匹配时该规则才被检查。通用规则始终都会检查。
高效 CSS 指南
避免通用规则
请确保规则不以通用类型选择器作为结束!
不要用标签名或 classes 来限定 ID 规则
如果规则拥有 ID 选择器作为其关键选择器,则不要为规则增加标签名。因为 ID 是唯一的,增加标签只会没必要地减缓匹配过程。
差
- button#backButton {…}
差
- .menu-left#newMenuIcon {…}
好