css进阶学习 选择符

在我最早开始写css的时候,其代码上的高自由度就一直很令我困惑。这就是说,同一个设计,如果让不同的人来实现,最终的代码一定是有差异的。但这存在一个问题,如果不同的人通过不同的方法以及代码风格,都从外观上实现了一样的设计,将很难评价谁做得更好。想来也是,既然都实现了设计,达到了目的,css这种没有程序逻辑的代码中,又能找出什么来说明谁做得更出色呢?

而如今,我认同的观念是,css这种描述性语言,仍然有着代码上的质量评判。评判标准就是可维护性(Maintainability)和性能(Performance),用比较通俗的话说,好的css,要对开发者的工作友好(dev-friendly),也要对浏览器友好(browser-friendly)。 本文将说明如何从css选择符的角度来提高css代码质量。

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

css选择符的概念,在之前的新手学习css优先级的开头部分也有提到,是指每一条样式规则中,描述把样式作用到哪些元素的部分,也即{}之前的部分。在本文,还要额外介绍一个概念:关键选择符(Key selector)。关键选择符就是在每一条样式规则起始的{之前的最后一个选择符,如下图:

css进阶学习 选择符

css选择符将确定后面的属性定义要作用到哪些元素,因此存在一个浏览器根据css选择符来应用样式到对应元素的匹配过程。关于浏览器的样式匹配系统,David Hyatt在Writing Efficient CSS for use in the Mozilla UI一文中提到了以下内容:

The style system matches a rule by starting with the rightmost selector and moving to the left through the rule's selectors. As long as your little subtree continues to check out, the style system will continue moving to the left until it either matches the rule or bails out because of a mismatch.

意思是说,浏览器引擎在样式匹配时,以从右向左的顺序进行。在具体匹配某一条样式规则时,这个从右向左的过程会一直持续,直到读取完整个选择符序列并完成匹配,或因某一个地方的不匹配而取消(然后转到另一条样式规则)。

至于为什么浏览器会选择这样的匹配顺序,你可以看看Stack Overflow上的相关讨论。大致上解释一下的话,由于最右边的关键选择符直接表示了样式定义应作用的元素,所以从右向左的顺序更利于浏览器在初始匹配的时候就确定有样式定义的元素集合,并更快地在找某一个元素的样式时避开大多数实际没有作用到的选择符。

更好的css选择符,是让浏览器在样式匹配过程中减少匹配查询次数,以更快的速度完成样式匹配,从而优化前端性能。这其中,也必须参考浏览器的对于样式从右向左的匹配顺序。

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

更具体的关键选择符

关键选择符是浏览器引擎在样式匹配时最先读取到的部分,因此,如果你在某一条样式规则中使用更特定、具体的选择符,可以帮助减少浏览器的查找匹配次数。

比如说下边这样的选择符:

.content .note span{}

最后一个span是关键选择符,而span这个标签,在网页中使用是非常多的。浏览器从span开始读取选择符,就可能会为因此在样式匹配上做了一些额外工作。

如果你确定只是想为具体处于那一个位置的span元素定义样式,更好的做法是为span命名class,比如命名为span.note_text,然后简单写为:

.note_text{}

使用class选择符

class选择符(类选择符)是最利于性能优化的选择符。相对于class,ID的缺点是只允许定义给一个元素,无法重用。而此外,它在使用上没有任何比class更好的地方。很多时候,你很难确定某一个元素是否是唯一的。另外,使用class来定义样式,而保留ID给javascript,一直是一个较好的实践。如果可以,不使用ID来定义样式。

而相对于class,标签在html中的重复性要更大,因此同样可能让浏览器在样式匹配时做更多的额外工作。如果可以,除css样式清零(reset)外,不使用标签选择符(也叫元素选择符)。

缩短选择符序列

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

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wzzxps.html