CSS选择器、优先级与匹配原理
为了分析 Bootstrap 源码, 所以的先把 CSS 选择器相关的东东给巩固好
废话就不多说了
计算指定选择器的优先级: 重新认识 CSS 的权重
- 通配选择符的权值 0,0,0,0
- 标签的权值为 0,0,0,1
- 类的权值为 0,0,1,0
- 属性选择的权值为
0,0,1,10,0,1,0 - 伪类选择的权值为 0,0,1,0
- 伪对象选择的权值为 0,0,0,1
- ID 的权值为 0,1,0,0
- important 的权值为最高 1,0,0,0
使用的规则也很简单,就是 选择器的权值加到一起,大的优先;如果权值相同,后定义的优先 。虽然很简单,但如果书写的时候没有注意,很容易就会导致 CSS 的重复定义,代码冗余。
从上面我们可以得出两个关键的因素:
- 权值的大小跟选择器的类型和数量有关
- 样式的优先级跟样式的定义顺序有关
记得以前看过一篇文章 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 的执行效率:
- 样式系统从最右边的选择符开始向左进行匹配规则。只要当前选择符的左边还有其他选择符,样式系统就会继续向左移动,直到找到和规则匹配的元素,或者因为不匹配而退出。
- 如果你非常在意页面的性能那千万别使用 CSS3 选择器。实际上,在所有浏览器中,用 class 和 id 来渲染,比那些使用同胞,后代选择器,子选择器(sibling, descendant and child selectors)对页面性能的改善更值得关注。
Google 资深 web 开发工程师 Steve Souders 对 CSS 选择器的效率从高到低做了一个排序:
-
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)
-
上面九种选择器中 ID 选择器的效率是最高,而伪类选择器的效率则是最低
-
详细的介绍大家还可以点击Writing efficient CSS selectors。