从覆盖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样式。

查了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规范

 

 

posted @ 2016-12-26 14:39  Whalefallsea  阅读(6190)  评论(0编辑  收藏  举报