從覆蓋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規范

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM