优先级

!important > 行内样式 > ID选择器 > 类选择器 > 标签 > 通配符 > 继承 > 浏览器默认属性

有一个简单的计算方法,即:

  • 内联样式表的权值为 1000
  • ID 选择器的权值为 100
  • Class 类选择器的权值为 10
  • HTML 标签选择器的权值为 1

注意:

  • 数字只是表明了思想,实际上一万个class也不如一个id的权重高
  • !important的优先级是最高的,但出现冲突时则需比较“四位数”;
  • 优先级相同时,则采用就近原则,选择最后出现的样式;
  • 继承得来的属性,其优先级最低;

浏览器读取选择器的规则

浏览器读取选择器,遵循的原则是从选择器的右边到左边读取。换句话说,浏览器读取选择器的顺序是由右到左进行的。因此,要避免一些常见的开销很大的css选择器模式,尽量编写高效的css选择器,从而加快页面渲染速度,缩短页面呈现时间。

1
2
3
4
5
<style type="text/css">
div#box p span.red {
color: red;
}
</style>

浏览器读取选择器的顺序如下:

  1. 查找页面上所有的class=redspan元素
  2. 查找1.结果的父元素中是否有p元素
  3. 查找2.结果中的父元素是否有id=box的div元素

选择器的最后一部分,也就是选择器的最右边部分被称为 关键选择器 (keyselector),它将决定 CSS 选择器的效率。

总结:ID和类名用于关键选择器上效率是最高的,而CSS3的仿伪类和属性选择器,虽然使用方便,但其效率却是最低的。

  • 网站编写CSS时,应该优先考虑使用class选择器,避免使用通配符选择器(*)和属性选择器(a[rel=”external”]),后代选择器与标签选择器结合使用也应避免。
  • 使用id选择器的性能最好,但是编写时要注意其唯一性,谨慎使用。
  • CSS3选择器(例如::nth-child(n)第n个孩子)在帮助我们锁定我们想要的元素的同时保持标记的干净和语义化,但事实是,这些花哨的选择器让更多的浏览器资源被密集使用。如果你关心页面性能的话,尽可能不用或者少用。

性能优化

  • 避免使用通用选择器
1
2
3
4
5
<style type="text/css">
.content * {
color: red;
}
</style>

浏览器匹配文档中所有的元素后分别向上逐级匹配 class 为 content 的元素,直到文档的根节点。因此其匹配开销是非常大的,所以应避免使用关键选择器是通配选择器的情况。

  • 不要在编写id规则时用标签名或类名
1
2
3
4
5
6
7
8
9
10
<style type="text/css">
// BAD
button#backButton {};
// BAD
.menu-left#newMenuIcon {};
// GOOD
#backButton {};
// GOOD
#newMenuIcon {};
</style>
  • 不要在编写class规则时用标签名
1
2
3
4
5
6
7
8
<style type="text/css">
// BAD
td.indented {};
// GOOD
.td-indented {}; // 语义化和标签名绑在一起
// BEST
.indented {}; // 语义化和标签无关
</style>
  • 把多层标签选择规则用class规则替换,减少css查找
1
2
3
4
5
6
<style type="text/css">
// BAD
table > tr > td {};
// GOOD
.table-td {};
</style>
  • 避免使用子选择器

后代选择器在CSS中是最昂贵的选择器。贵得要命——尤其是把它和标签或通配符放在一起!

1
2
3
4
5
6
<style type="text/css">
// BAD
table tr td {};
// Better BUT STILL BAD
table > tr > td {};
</style>

标签后面最好永远不要再增加子选择器

1
2
3
4
5
6
7
8
9
10
<style type="text/css">
// BAD
table > tr > td {};
// GOOD
.table-td {};
// BAD
table[isServer="true"] > tr > .td {};
// GOOD
.table-td[isServer="true];
</style>
  • 依靠继承来优化
1
2
3
4
5
6
7
8
9
10
<style type="text/css">
// BAD
#menu > .menu-item {
color: red;
};
// GOOD
#menu {
color: red;
}
</style>
  • 避免单规则的属性选择器

属性选择器根据元素的属性是否存在或其属性值进行匹配,如下例规则会把herf属性值等于 ”#index” 的链接元素设置为红色:

1
2
3
4
5
<style type="text/css">
.selected [href="#map"] {
color: red;
}
</style>

其匹配开销是非常大的,浏览器先匹配所有的元素,检查其是否有href属性并且herf属性值等于”#index”, 然后分别向上逐级匹配class为selected的元素,直到文档的根节点。所以应避免使用关键选择器是单规则属性选择器的规则。

  • 避免类正则的属性选择器

CSS3添加了复杂的属性选择器,可以通过类正则表达式的方式对元素的属性值进行匹配。当然这些类型的选择器定是会影响性能的,正则表达式匹配会比基于类别的匹配会慢很多。大部分情况下我们应尽量避免使用 *=, |=, ^=, $=, 和 ~=语法的属性选择器。

  • 移除无匹配的样式

    移除无匹配的样式,有两个好处:

    • 删除无用的样式后可以缩减样式文件的体积,加快资源下载速度
    • 对于浏览器而言,所有的样式规则的都会被解析后索引起来,即使是当前页面无匹配的规则。移除无匹配的规则,减少索引项,加快浏览器查找速度