By
running_snail
更新日期:
曾几何时,我天真的认为“选择器肯定是越详细,层数越多越好呗”。现在觉得自己以前真是图样图森破…
谨以此文,祭奠那些被我误用的CSS, orz。
此文重在讨论如何书写高效的CSS选择器。如有错误,欢迎指正,O(∩_∩)O
浏览如何识别选择器?
“浏览器读取选择器的顺序是由右到左进行”—《Efficiently Rendering CSS》Chris Coyier
例如:
1
| ul > li a[title="home"] {…}
|
浏览器将首先解释 a[title=”home”]。这个最先解释选择器是最后被选择的元素的“关键选择器”。
再如:
1
| a img, div > p, h1 + [title] {…}
|
此处关键选择器为 img,p,title
关键选择器示例:
1 2 3 4 5 6 7 8
| #main-navigation {…} body.home #page-wrap {…} .main-navigation {…} ul li a.current {…} ul {…} /* Tag */ ul li a {…} * {…} #content [title='home'] {…}
|
越具体的关键选择器,其性能越高。
如何写有效率的CSS选择器?
选择器效率排序
选择器效率从高到低排列如下
- id选择器(#myid)
- 类选择器(.myclassname)
- 标签选择器(div,h1,p)
- 相邻选择器(h1+p)
- 子选择器(ul > li)
- 后代选择器(li a)
- 通配符选择器(*)
- 属性选择器(a[rel=”external”])
- 伪类选择器(a:hover,li:nth-child)
一些写高效CSS选择器的规则
不要在ID选择器前加标签名或类
如果一个规则的关键选择器是ID选择器,不要在其前面加上标签名或类名。因为ID是唯一的加上一个标签名会降低匹配速度。
1
| .menu-left#newMenuIcon {…}
|
不要在类前加标签名
之前的观念依然适用,虽然类可在同个页面中被使用多次,但他们仍比标签稀罕。
- GOOD (tag+class命名法 缺点是不够灵活,如果改了标签类名也要换)
尽可能使用最具体的类别
1
| a[target=_blank] > p > span {…}
|
避免使用后代选择器
后代选择器是CSS中代价最昂贵的选择器。尤其是标签或是通配符选择器,它将昂贵的可怕。
1
| table > tbody > tr > th {…}
|
标签分类规则不应该包含子元素选择器
避免在标签类型规则使用子元素选择器。这会使匹配时间增多。
1
| table > tbody > tr > th {…}
|
避免使用通配符选择器
1
| .selected * {color: red;}
|
浏览器会匹配文档中所有元素,然后分别向上逐级匹配class为selected的元素,
知道文档的根节点,因此匹配花销是非常大的,通常比开销最小的ID选择器高出1~3个数量级,所以应避免使用关键选择器是通配选择器的规则。
避免使用单规则的选择器
1
| .selected [href=”#index”] {color: red;}
|
其匹配开销是非常大的,浏览器先匹配所有的元素,检查其是否有href属性并且herf属性值等于”#index”, 然后分别向上逐级匹配class为selected的元素,直到文档的根节点。所以应避免使用关键选择器是单规则属性选择器的规则。
避免使用类正则的选择器
CSS3添加了复杂的属性选择器,可以通过类正则表达式的方式对元素的属性值进行匹配。当然这些类型的选择器定是会影响性能的,正则表达式匹配会比基于类别的匹配会慢很多。大部分情况下我们应尽量避免使用 *=, |=, ^=, $=, 和 ~=语法的属性选择器。
适当调整你的选择器
1
| #main-navigation li a { font-family: Georgia, Serif; }
|
- GOOD (如果你需要的只是改变字体,这样写可能更有效)
1
| #main-navigation { font-family: Georgia, Serif; }
|
- GOOD (如果要使用后代选择器,适当地缩小层级,降低CSS权重)
笔者认为…
笔者认为虽然ID是最高效的选择器,不过如果把所有要选择的元素全都写上ID也是一件很蠢的事…
ID选择器权重太高,不存在任何可重用性,因此要尽量少用ID选择器。
笔者倾向于使用类选择器,简短且语义化的命名,同时书写模块化的CSS会使你的CSS更容易扩展和可重用。
参考文献:
[1] CSS选择器的优化
[2] Writing efficient CSS
[3] Efficiently Rendering CSS
[4] 高性能CSS
[5] 你应该知道的一些事情——CSS权重