样式优先级
首先简单说几个定义样式的方式:
元素内嵌:
<li><a href="" style="color:#ffffff;">SHOW</a></li>
文档内嵌:
<style type="text/css"> /* 内部样式 */ h3 { color: green; } </style>
外部样式:
<link rel="stylesheet" href="css/style.css">
上面这些都是题外话,接下来我来说说我遇到的问题,先看代码
<header class="navbar navbar-default navbar-fixd-top " id="benner"> <div class="container"> <a href="#" class="scrollable">FishShe</a> <button class="navbar-toggle collapsede"> <span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <nav class="collapse navbar-collapse"> <ul class="nav navbar-nav navbar-right"> <li class="active"><a href="">ABOUT</a></li> <li><a href="">SHOW</a></li> <li><a href="">CONTACT</a></li> </ul> </nav> </div> </header>
在这里,我想要修改bootstrap默认a元素的样式。最开始我是这样做的,引入我自己写的外部样式
<link rel="stylesheet" href="show.css"> /*外部样式*/ a { color: #ffffff; }
结果是这样的,为什么会这样,我不是把自己的样式表放在bootstrap引用的后面了么,为什么没有覆盖bootstrap样式。
查了css2规范之后我才知道是怎么回事。我们要先来了解一下css计算选择器的特殊性,css2规范里是这样描述的:
- 如果声明来自一个'style'属性而不是一条选择器样式规则,算1,否则就是0 (= a)(HTMl中,一个元素的"style"属性值是样式表规则,这些属性没有选择器,所以a=1,b=0,c=0,d=0)
- 计算选择器中ID属性的数量 (= b)
- 计算选择器中其它属性和伪类的数量 (= c)
- 计算选择器中元素名和伪元素的数量 (= d)
特殊性只根据选择器的形式来定。特殊的,一个"[id=p33]"形式的选择器被算作一个属性选择器(a=0, b=0, c=1, d=0),即使id属性在源文档的DTD中被定义为"ID"
4个数连起来a-b-c-d(在一个基数很大的数字系统中(in a number system with a large base))表示特殊性。
一些示例:
* {} /* 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 */
也就是说,abcd相互比较,若a相同则比较b,如此类推,比如说比较到c的时候,样式一比样式二大,则特殊性(优先级)高。举个简单例子:
<head> <meta charset="UTF-8"> <title>A Pen by FishShe</title> <link rel="stylesheet" href="css/style.css"> <link rel="stylesheet" href="css/style2.css"> </head> <body> <body> <div> <h3>测试!</h3>//这里应该为绿色
</div> </body> </body> /*style*/ h3 { color: red; } /*style2*/ h3 { color: green; }
当我把style样式表中的样式改为
div h3 {
color: red;
}
这时h3里的字体为红色,因为这时它的权重为0,0,0,2比较style2样式表中的0,0,0,1,abc相同,但是d的值比style2的大。说到这里,我不得不提一下,最开始提到的定义样式的几个方式,其实都是相同的来源,即编写者常规声明。当你为样式添加!important时,就是编写者重要声明,当来源和重要性相同的时候就根据特殊性来排序。所以我个人认为“文档内嵌的优先级比外部样式优先级高”这句话是不对的,它们是同一个来源;当来源、重要性和选择器特殊性一样的时候,则是后声明的生效,简单试一下,就可以知道外部样式的链接在文档内嵌(style结束标签)后面的话,生效的是外部样式。
现在说回使用bootstrap的问题,我想要使用自己的样式改变bootstrap中a标签的默认样式。bootstrap的a标签样式是
.navbar-default .navbar-nav>li>a { color: #777;
//它的权重是0,0,2,2
我可以直接这样:
<li><a href="" style="color:#ffffff">SHOW</a></li>//它的权重是1,0,0,0
但是这样我需要每个a都去设置,我还可以这样:
.navbar-default .navbar-nav>li>a { color: #ffffff; } //它的权重是0,0,2,2,但是它是后定义的,可以生效。
最后我选择这样的,因为我需要全部的a标签都使用相同的我定义的样式
a{ color:#ffffff!important; } //直接改为重要声明
总的来说,当来源和重要性一样的时候,要去覆盖其他同样的属性的时候,就需要提高你的样式特殊性了(可以添加一个类、加一个父元素等等),特殊性相同时,后声明的生效。另外如果相同元素都声明了!important的话,就还是要看特殊性了。所以说,不要滥用important,最需要的时候用就是最好的。关于更多关于css层叠的信息可以查阅css2.1规范。