css层叠管理
css的层叠决定哪些样式要被应用于元素的一套规则。它指定Web浏览器如何应用同一标签的多个样式,以及CSS属性发生冲突时,它该怎么做。这里,我们可以从继承来的样式和元素自生拥有的样式来讨论。
继承来的样式
对于某个元素继承来的样式,css又分两种情况。第一种,若继承来的样式中css属性不发生冲突(即同一个css属性在不同的标签里面定义了不同的值),则这些属性可以很融洽的合作,即都运用在这个元素上。第二种,若是继承来的css属性有冲突,那么只有最靠近这个元素的继承样式起作用。例如有下面的情况:
<html> <head> <title>优先级</title> <style type = "text/css"> div { color: red; } p { color: orange; } </style> </head> <body> <div> <p> <span>我是什么颜色</span> </p> </div> </body> </html>
运行结果:
上面的css代码中,div和p标签都定义了color属性,但是最后文本的颜色继承了p标签的属性,显示为黄色。因为p标签离span标签最近,所以span继承了它的属性。即时有使用了!important(可以改变样式的权重)也是如此:
<html> <head> <title>优先级</title> <style type = "text/css"> div { color: red !important; } p { color: orange; } </style> </head> <body> <div> <p> <span>我是什么颜色</span> </p> </div> </body> </html>
运行结果:
继承来的样式和自身样式
继承来的样式和某元素自身的样式也有两种情况,若继承来的样式和元素自身的样式css属性没有冲突,则它们也可以很好的合作,若是有冲突,总是元素自身的样式起作用:
<html> <head> <title>优先级</title> <style type = "text/css"> p { color: orange ; /*color: orange !important*/ } span { color: red; } </style> </head> <body> <div> <p> <span>我是什么颜色</span> </p> </div> </body> </html>
运行结果:
span标签和p标签都定了color属性,span自身的color属性得到应用,而忽略继承来的p属性。即使p标签运用了!important也一样。
元素的自身样式
元素的自身样式也分两种情况,如果某个元素自身的样式中css属性没有冲突,那么这些样式可以协作工作,如果有冲突,则需要分以下两步来决定:
1 通过计算权重值来决定运用哪个样式
下面的内容引用自博客园$雨$的一片文章
有很多文章在说到权重值的时候,都会给出如下公式:
内联样式(即直接用style属性声明在元素标签里)权重值为1000;
id选择器的权重值为100;
类选择器的权重值为10;
标签选择器的权重值为1;
按照这种方法来计算,大多数情况不会出错,但是请看下面的例子:
<html> <head> <title>优先级</title> <style type = "text/css"> body div div div div div div div div div span { color: orange; } .text { color: red; } </style> </head> <body> <div> <div> <div> <div> <div> <div> <div> <div> <div> <span class = "text" >我是什么颜色</span> </div> </div> </div> </div> </div> </div> </div> </div> </div> </body> </html>
运行结果:
如果按照上面的公式计算,第一条样式的选择器权重应该是11,第二条样式的权重为10,照理应该运用第一条规则,可是结果却是字显示为红色,应用了第二条规则,这就是上面的公式局限的地方。接下来就来解释为什么会应用第二条规则的原因。
实际上,对于权重值的计算与比较,应该分成A B C D四个层次:
如果样式写在标签的style属性里面,则A = 1,否则 A = 0。
计算ID选择器的数量,如果有则B = 1, 否则B = 0。
计算类、伪类以及其他属性的数量(不包括伪元素),有则C = 1,否则C = 0。
计算伪元素及标签的数量,有则D = 1,否则D = 0。
比如:
对于<span style = "color: red">文本</span> 根据上面的方法A = 1 B = 0 C = 0 D = 0(简写为1000);
对于#idName这样的选择器,则为A = 0 B = 1 C = 0 D = 0(简写为0100);
对于.className这样的选择器,则为A = 0 B = 0 C = 1 D = 0(简写为0010);
对于p这样的普通标签,则为A = 0 B = 0 C = 0 D = 1(简写为0001);
通过观察后面的简写形式,就会发现为什么有很多地方将内联样式的权重定义为1000,id选择器的权重定义为100,类选择器的权重定义为10, 标签选择器的权重定义为1的原因。
下面是更多的例子:
- * {} /* a=0 b=0 c=0 d=0 -> specificity = 0,0,0,0 */
- li {} /* a=0 b=0 c=0 d=1 -> specificity = 0,0,0,1 */
- li:first-line {} /* a=0 b=0 c=0 d=2 -> specificity = 0,0,0,2 */
- ul li {} /* a=0 b=0 c=0 d=2 -> specificity = 0,0,0,2 */
- ul ol+li {} /* a=0 b=0 c=0 d=3 -> specificity = 0,0,0,3 */
- h1 + *[rel=up]{} /* a=0 b=0 c=1 d=1 -> specificity = 0,0,1,1 */
- ul ol li.red {} /* a=0 b=0 c=1 d=3 -> specificity = 0,0,1,3 */
- li.red.level {} /* a=0 b=0 c=2 d=1 -> specificity = 0,0,2,1 */
- #x34y {} /* a=0 b=1 c=0 d=0 -> specificity = 0,1,0,0 */
- style=”" /* a=1 b=0 c=0 d=0 -> specificity = 1,0,0,0 */
在比较权重值的时候,对于A B C D四个层次是依次比较,如果两个样式中有一个样式的A值大,则这个样式的优先级大;如果A值相同,再比较B值,B值大的样式优先级大;若果B值相同,再比较C值,依次类推。如果A B C D四个值都相同,那么后出现的样式优先级大。
那么,让我们分析刚才html代码的情况。第一个样式拥有11个标签,因此A = 0 B = 0 C = 0 D = 11(简写为000 11);第二个样式拥有一个类名,因此A = 0 B = 0 C = 1 D = 0(简写为0010),依次比较,样式二胜出,因此会运用样式二。
内部样式表和外部样式表
对于内部样式表和外部样式表,可以运用相同的方法。首先比较权重值,由权重值决定样式的优先级;权重值相等,那么样式的声明顺序决定样式的优先级,后声明的样式优先级大。因此内部样式表和外部样式表在html文件中的顺序,也能影响到样式优先级的顺序。
特殊的!important
在比较元素自身样式的优先级的时候,声明!important的样式优先级最高,比如:
样式一: p span {color: red !important; font-size: 10px;}
样式二: p .text {color:orange; font-size: 12px;}
他们都作用于span元素,.text是span元素的一个类名。代码如下:
<html> <head> <title>优先级</title> <style type = "text/css"> p span { color: red !important; font-size: 10px; } .text { color: orange; font-size: 50px; } </style> </head> <body> <div> <p> <span class = "text">我是什么颜色</span> </p> </div> </body> </html>
运行结果:
样式一的权重值为A = 0 B = 0 C = 0 D =2(简写为0002),样式二的权重值为A = 0 B = 0 C = 1 D = 0(简写为0010)。按照上面的比较方式,应该样式二优先级大,文本颜色应为orange,字体为50px;但是实际情况是文本颜色为red,但是字体认为50px。出现这个原因就是样式一种的color属性被声明成了!important,它的优先级最大,因此优先应用它,但font-size还是按比较的结果执行。
另外,若两个样式的权重值一样,而且都有!important,那么这是就由样式的声明顺序决定,靠后的样式将胜出,优先级大。
!important属性容易造成混乱,最好不要使用。
总结
对于css的层叠规则,作出如下总结:
1 分清元素的继承样式和自身样式
2 看继承样式和自身样式是否冲突,若冲突,自身样式总是胜出(即使继承样式有!important)
3 接下来看自身样式是否冲突,若冲突,按照权重值的比较规则比较
4 最后考虑!important的影响
更详细请参看《KB005: CSS层叠》。