从覆盖bootstrap样式谈css选择器优先级

时间:2023-03-09 16:39:21
从覆盖bootstrap样式谈css选择器优先级

样式优先级

首先简单说几个定义样式的方式:

元素内嵌:

<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样式。

从覆盖bootstrap样式谈css选择器优先级

查了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: #;
//它的权重是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规范