当我们写CSS的时候需要注意有些选择器在级联(cascade)上会高于其它选择器,我们写在最后面的选择器将不一定会覆盖前面我们写在同一个元素的样式。那么你如何计算指定选择器的优先级?如果你考虑到将优先级表示为用逗号隔开的四个数字就会相当简单,比如:1, 1, 1, 1 或0, 2, 0, 1
第一个数字(a)通常就是0,除非在标签上使用style属性;
第二个数字(b)是该选择器上的id的数量的总和;
第三个数字(c)是用在该选择器上的其它属性选择器和伪类的总和。这里包括class (.example) 和属性选择器(比如 li[id=red]);
第四个数字(d)计算元素(就像table、p、div等等)和伪元素(就像:first-line等);
通用选择器(*)是0优先级;
如果两个选择器有同样的优先级,在样式表中后面的那个起作用。
让我们看几个例子,这样或许比较容易理解些:
#sidebar h2 — 0, 1, 0, 1
h2.title — 0, 0, 1, 1
h2 + p — 0, 0, 0, 2
#sidebar p:first-line — 0, 1, 0, 2
在下面的例子中,第一个将会起作用,因为它比第二个优先级高:
#sidebar p#first { color: red; } — 0, 2, 0, 1
#sidebar p:first-line { color: blue; } — 0, 1, 0, 2
层叠次序
当同一个 HTML 元素被不止一个样式定义时,会使用哪个样式呢?
一般而言,所有的样式会根据下面的规则层叠于一个新的虚拟样式表中,其中数字 4 拥有最高的优先权。
- 浏览器缺省设置
- 外部样式表
- 内部样式表(位于 head 标签内部)
- 内联样式(在 HTML 元素内部)
因此,内联样式(在 HTML 元素内部)拥有最高的优先权,这意味着它将优先于以下的样式声明: 标签中的样式声明,外部样式表中的样式声明,或者浏览器中的样式声明(缺省值)。
提示:如果你使用了外部文件的样式在内部样式中也定义了该样式,则内部样式表会取代外部文件的样式。
多重样式优先级顺序
下列是一份优先级逐级增加的选择器列表,其中数字 7 拥有最高的优先权:
- 通用选择器(*)
- 元素(类型)选择器
- 类选择器
- 属性选择器
- 伪类
- ID 选择器
- 内联样式
!important 规则例外
当 !important 规则被应用在一个样式声明中时,该样式声明会覆盖CSS中任何其他的声明,无论它处在声明列表中的哪里。尽管如此,!important规则还是与优先级毫无关系。使用 !important 不是一个好习惯,因为它改变了你样式表本来的级联规则,从而使其难以调试。
一些经验法则:
- Always 要优化考虑使用样式规则的优先级来解决问题而不是 !important
- Only 只在需要覆盖全站或外部 css(例如引用的 ExtJs 或者 YUI )的特定页面中使用 !important
- Never 永远不要在全站范围的 css 上使用 !important
- Never 永远不要在你的插件中使用 !important
权重计算:
以下是对于上图的解释:
- 内联样式表的权值最高 1000
- ID 选择器的权值为 100
- Class 类选择器的权值为 10
- HTML 标签选择器的权值为 1
利用选择器的权值进行计算比较,em 显示蓝色,我们提供了详细的代码参考:
<style type="text/css"> #redP p { /* 权值 = 100+1=101 */ color:#F00; /* 红色 */ } #redP .red em { /* 权值 = 100+10+1=111 */ color:#00F; /* 蓝色 */ } #redP p span em { /* 权值 = 100+1+1+1=103 */ color:#FF0;/*黄色*/ } </style> </head> <body> <div id="redP"> <p class="red">red <span><em>em red</em></span> </p> <p>red</p> </div> </body> </html>
CSS 优先级法则:
- A 选择器都有一个权值,权值越大越优先;
- B 当权值相等时,后出现的样式表设置要优于先出现的样式表设置;
- C 创作者的规则高于浏览者:即网页编写者设置的CSS 样式的优先权高于浏览器所设置的样式;
- D 继承的CSS 样式不如后来指定的CSS 样式;
- E 在同一组属性设置中标有"!important"规则的优先级最大;