CSS选择器、优先级与匹配原理

为了分析 Bootstrap 源码, 所以的先把 CSS 选择器相关的东东给巩固好

废话就不多说了

CSS 2.1 selectors, Part 1

计算指定选择器的优先级: 重新认识 CSS 的权重

  1. 通配选择符的权值 0,0,0,0
  2. 标签的权值为 0,0,0,1
  3. 类的权值为 0,0,1,0
  4. 属性选择的权值为 0,0,1,1 0,0,1,0
  5. 伪类选择的权值为 0,0,1,0
  6. 伪对象选择的权值为 0,0,0,1
  7. ID 的权值为 0,1,0,0
  8. important 的权值为最高 1,0,0,0

使用的规则也很简单,就是 选择器的权值加到一起,大的优先;如果权值相同,后定义的优先 。虽然很简单,但如果书写的时候没有注意,很容易就会导致 CSS 的重复定义,代码冗余。

从上面我们可以得出两个关键的因素:

  1. 权值的大小跟选择器的类型和数量有关
  2. 样式的优先级跟样式的定义顺序有关

记得以前看过一篇文章 256 个 class 类名选择器干掉一个 id 选择器实例页面

http://www.zhangxinxu.com/study/201208/256-class-fire-an-id.html

Gecko overflows the count of classes into the count of IDs, each of which holds 8 bits.

— Cameron McCormack (@heycam) August 16, 2012

给出的答案是: 所有的类名 (classes) 都是以8 字节字符串存储的。8 字节所能 hold 的最大值就是 255. 当同时出现 256 个 class, 势必会越过其边缘,溢出到 id 区域。

 

总结:

比较同一级别的个数,数量多的优先级高,如果相同即比较下一级别的个数 ,至于各级别的优先级,大家应该已经很清楚了,就是:

important > 内联 > ID > 类 > 标签 | 伪类 | 属性选择 > 伪对象 > 继承 > 通配符 通配符 > 继承

这也就解释了为什么 11 个标签的定义会比不上 1 个类的定义,1 个类加 11 个标签会比不上 2 个类的权重高。

 

 

选择器种类

查阅资料归纳下大概有如下几种:

  • 通配选择器

  • 类型选择器

  • ID 选择器

  • 类选择器

  • 包含选择器

  • 子元素选择器

  • 相邻兄弟选择器

  • 属性选择器

css1-css3 提供非常丰富的选择器,但是由于某些选择器被各个浏览器支持的情况不一样,所以很多选择器在实际 css 开发中很少用到

 

关于 CSS 的执行效率:

  1. 样式系统从最右边的选择符开始向左进行匹配规则。只要当前选择符的左边还有其他选择符,样式系统就会继续向左移动,直到找到和规则匹配的元素,或者因为不匹配而退出
  2. 如果你非常在意页面的性能那千万别使用 CSS3 选择器。实际上,在所有浏览器中,用 class 和 id 来渲染,比那些使用同胞,后代选择器,子选择器(sibling, descendant and child selectors)对页面性能的改善更值得关注。

 

Google 资深 web 开发工程师 Steve Souders 对 CSS 选择器的效率从高到低做了一个排序:

  1. 1.id 选择器(#myid)2. 类选择器(.myclassname)3. 标签选择器(div,h1,p)4. 相邻选择器(h1+p)5. 子选择器(ul < li)6. 后代选择器(li a)7. 通配符选择器(*)8. 属性选择器(a[rel="external"])9. 伪类选择器(a:hover,li:nth-child)

  2. 上面九种选择器中 ID 选择器的效率是最高,而伪类选择器的效率则是最低

  3. 详细的介绍大家还可以点击Writing efficient CSS selectors