商城首页欢迎来到中国正版软件门户

您的位置: 首页 > 文章列表 > 编程开发 > css进阶学习 选择符

css进阶学习 选择符

  发布于2026-07-22 阅读(0)

扫一扫,手机访问

初学CSS时,最让人困惑的莫过于它那极高的自由度——同一个设计交给不同的人来做,最终产出的代码几乎不可能一模一样。问题随之而来:如果不同的实现方式,不同的代码风格,最终在视觉上呈现的效果完全一致,我们又该如何评判孰优孰劣?CSS毕竟是门没有程序逻辑的描述性语言,难道还能从中分出高下?

如今,我越来越认同一个观点:即使是描述性语言,CSS同样存在代码质量的评判标准。核心就是两个维度——可维护性性能。用大白话说,好的CSS既要对开发者友好(dev-friendly),也要对浏览器友好(browser-friendly)。这篇文章就从选择符的角度,聊聊如何写出更高质量的CSS代码。

关键选择符与浏览器的样式规则匹配原理

CSS选择符,就是每一条样式规则中{}之前的部分,描述的是“把样式作用到哪些元素上”。这里需要引入一个额外概念:关键选择符。它指的是每条样式规则起始的{之前的最后一个选择符,如下图所示:

css进阶学习 选择符

CSS选择符决定了属性定义要作用到哪些元素,因此存在一个浏览器根据选择符来匹配样式的过程。关于浏览器的匹配机制,Da vid Hyatt在Writing Efficient CSS for use in the Mozilla UI中提过:

样式系统匹配一条规则时,从最右边的选择符开始,然后向左移动,遍历规则中的选择符序列。只要你的小小子树不断匹配成功,样式系统就会继续向左移动,直到匹配整个规则,或者因为某个位置不匹配而放弃。

也就是说,浏览器引擎采用的是从右向左的顺序进行样式匹配。为什么这么设计?可以看看Stack Overflow上的相关讨论。简单解释一下:最右边的关键选择符直接表示了样式定义应作用的元素,从右向左的顺序能让浏览器在初始匹配时就确定有样式定义的元素集合,从而更快地跳过大多数实际上没有作用到的选择符。

好的CSS选择符,就是要让浏览器在样式匹配过程中减少查询次数,以更快的速度完成匹配,进而优化前端性能。这其中,必须充分理解浏览器的从右向左匹配顺序。

CSS选择符的正确使用方式:更特定

更具体的关键选择符

关键选择符是浏览器引擎最先读取的部分。如果你在某条样式规则中使用更具体的选择符,就能帮助减少查找匹配次数。比如:

.content .note p{}

这里的p是关键选择符,而p标签在网页中非常常见。浏览器从p开始读取,可能会因为匹配了太多元素而做额外工作。如果你只是想为特定位置的p定义样式,更好的做法是给它命名class,比如p.note_text,然后直接写:

.note_text{}

使用class选择符

class选择符是性能最优的选择符。相比之下,ID的缺点在于只能定义给一个元素,无法重用,而且在使用上没有任何比class更好的地方。很多时候你很难确定某个元素是否唯一。一个比较好的实践是:用class定义样式,把ID留给Ja vaScript。如果可以,尽量不用ID来定义样式。

而与class相比,标签在HTML中的重复性更大,同样可能让浏览器做额外工作。除了CSS样式清零(reset)之外,尽量少用标签选择符(元素选择符)。

缩短选择符序列

继承写法(这里指CSS关系选择符中的包含选择符)非常常用。它的初衷是:如果有两个元素标签相同或class命名相同,加入父元素的选择符组成序列,就能避免在不需要时样式互相影响。比如.confirm_layer .submit_btn表示:class名为submit_btn,且有一个class名为confirm_layer的父元素,才应用样式。

但避免互相影响,不代表可以随意使用继承选择符。浏览器会从右向左读取整个序列,直到匹配完成或因不匹配而取消。因此,短的选择符序列更有利于浏览器快速完成匹配。冗长的序列则被认为是低效的,比如:

.header ul li .na v_link{}

建议写成:

.header .na v_link{}

一般来说,不超过3层的继承层级就能满足实际开发需求。应减少不必要的层级,使用更短的选择符序列。

另外,较长的选择符序列还有一个问题:它会导致CSS优先级计算值偏高。以后如果需要写新样式来覆盖它,就必须写更长的选择符(或者使用ID)才能获得更高优先级,这对性能和代码可读性都不利。

避免链式选择符

链式选择符是对单个元素同时写了多个选择符判定。比如p.name表示class名为name且标签为p的元素才应用样式。这些判定可以是ID、标签、class的任意组合。

但链式选择符是过度定义的,不利于重用,也不利于性能。例如:

a#author{}

建议写成:

#author{}

这里的a是多余的——一个ID只对应一个元素,没必要再强调标签是什么(class同理)。再比如:

.content p.arrow{}

建议写成:

.content .arrow{}

p.arrow中的p也是不必要的——它让浏览器多了一项检查:class名为arrow的元素的标签是不是p,从而降低了性能。如果去掉这个限定,.arrow的样式定义就可以用在更多元素上,重用性更好。否则,你还得告诉别人:使用这个样式只能用在p标签上。

同理,多个class的链式写法,比如.tips.succuss{},建议更改命名,写成:

.tips_succuss{}

这样能帮助浏览器减少额外的样式匹配工作。

顺带一提,IE6对链式选择符存在一个bug:多个class写在一起如.class1.class2.class3,正常情况是只有同时拥有全部class的元素才应用样式,但IE6只认最后一个,即符合.class3的元素就会应用样式。

例外情况

前面这些建议,主要是从浏览器渲染性能优化和代码重用性角度分析得出的理论结果。实际使用中不必教条地遵守。比如,如果你确实想为class名为intro的元素内的所有a标签都加上样式,那么.intro a这样的选择符就是明智的。

结语

关于高效的CSS选择符,还可以参考Google Developer中的Use efficient CSS selectors。如今现代浏览器在样式匹配上已经有了更多优化(参考CSS Selector Performance has changed!),有些方面我们不再需要过分担心。但这并不意味着可以随意写选择符——CSS选择符性能优化依然存在。你的选择符应该更好地体现你的意图,而不是随心所欲。更重要的是,以这样一种经过思考的方式来写CSS选择符,并不是什么难事。只要你想,形成这种习惯,自然就能在这方面做得更好,何乐而不为呢?

本文转载于:https://www.jb51.net/article/161814.htm 如有侵犯,请联系zhengruancom@outlook.com删除。
免责声明:正软商城发布此文仅为传递信息,不代表正软商城认同其观点或证实其描述。

热门关注