一篇文章帶你初步瞭解—CSS特指度

CSS特指度

說明

這篇博客在在兩臺電腦上分別完成的,故而有些截圖是Firefox,有些是Chrome,有些改動了瀏覽器的用戶樣式表,有些沒改,但不會影響閱讀,特此說明,勿怪。css

CSS選擇器

單個CSS選擇器

css選擇器決定css樣式能渲染到對應的元素上。html

元素選擇器:
在這裏插入圖片描述瀏覽器

Class選擇器:
在這裏插入圖片描述
ID選擇器:
在這裏插入圖片描述spa

多個CSS選擇器

瀏覽器在處理單獨的id、class和元素選擇器時如何渲染的問題很好理解,但要在兩種甚至三種不一樣選擇器同時做用於相同的元素的狀況下,瀏覽器又該如何渲染呢?3d

好比3個選擇器做用在同一個元素身上的例子:code

<!DOCTYPE html>
<html>
    <head>
        <meta name="charset" content="utf-8"/>
        <title>ICE計算公式</title>
        <style type="text/css">
            #title {
                color : blue;
            }
            .red {
                color : red;
            }
            p {
                color : brown;
            }
        </style>
    </head>
    <body>
        <p id="title" class="red">這是標題</p>
    </body>
</html>

得出結果:
在這裏插入圖片描述
當3個不一樣的選擇器(ID、Class、元素)同時做用於同一元素上時,瀏覽器渲染時選擇的樣式爲ID選擇器聲明的樣式,這是由於ID選擇器的特指度高於Class選擇器,而Class選擇器的特指度高於元素選擇器......htm

那麼應該怎麼計算每一個選擇器特指度,要解決這個問題,不得不提到ICE計算公式:ID-Class-Element。blog

ICE計算公式

關於ICE計算公式錯誤的理解

注:我在過去很長一段時間都是按照這種錯誤的思想來理解ICE計算公式的,務必注意。排序

關於ICE計算公式,常常看到這樣的說法(這是錯誤的):繼承

!important ID Class Element
特指度 1000 100 10 1

Element特指度爲1,class特指度爲10,ID特指度爲100,!important爲1000。

若是按照這樣理解,是否是能夠說11個class的特指度爲10 * 11 === 110,它是確定比1個Id的特指度要大的,但在我實踐後,我發現不能這樣去理解,就好比下面的例子:

<!DOCTYPE html>
<html>
    <head>
        <meta name="charset" content="utf-8"/>
        <title>11個class是否比1個ID特指度大</title> 
        <style type="text/css">
            #id {
                color : green;
            }
            .class1.class2.class3.class4.class5.class6.class7.class8.class9.class10.class11 {
                color: red;
            }
        </style>
    </head>
    <body>
        <p id="id" class="class1 class2 class3 class4 class5 class6 class7 class8 class9 class10 class11">p標籤</p>
    </body>
</html>

若是按照class特指度爲十、id爲100的邏輯來理解,110 大於 100,最後p標籤的color屬性值應該爲red,可是實際狀況倒是:
在這裏插入圖片描述
標籤的color屬性值爲green。形成這樣結果的緣由是由於無論有多少個class選擇器,Id選擇器的特指度就是比class選擇器的特指度大。就比如奧運會排名,先比較金牌,金牌數量多者排前面,數量少者排後面,在出現金牌數量相同時纔會以銀牌的數量來比較。Id選擇器就比如金牌,而class選擇器就比如銀牌。當Id選擇器數量不一致時,後續操做壓根就不會去比較class選擇器,因此class選擇器的數量再多,也是無效的。

不一樣選擇器對應的特指度

選擇器共有:

  1. ID選擇器
  2. Class選擇器
  3. 元素選擇器
  4. 屬性選擇器
  5. 僞類選擇器
  6. 僞元素選擇器

ID選擇器

\(\color{#FF3030}{Selector Specificity: (1, 0, 0)}\)

#title {
	color : blue;
}

Class選擇器

\(\color{#FF3030}{Selector Specificity: (0, 1, 0)}\)

.red {
	color : red;
}

元素選擇器

\(\color{#FF3030}{Selector Specificity: (0, 0, 1)}\)

p {
	color : brown;
}

屬性選擇器

\(\color{#FF3030}{Selector Specificity: (0, 1, 0)}\)

[id="title"] {
    color : black;
}

僞類選擇器

\(\color{#FF3030}{Selector Specificity: (0, 1, 0)}\)

注意:p:hover的特指度爲 (0, 1, 1),由於它包含了元素選擇器和僞類選擇器

p:hover {
	color: #FF00FF
}

僞元素選擇器

\(\color{#FF3030}{Selector Specificity: (0, 0, 1)}\)

注意:p::after的特指度爲 (0, 0, 2),由於它包含了元素選擇器和僞元素選擇器

p::after {
    content: "元";
}

代碼:

<!DOCTYPE html>
<html>
    <head>
        <meta name="charset" content="utf-8"/>
        <title>6種選擇器的特指度</title>
        <style type="text/css">
            #title {
                color : blue;
            }
            .red {
                color : red;
            }
            p {
                color : brown;
            }
            [id="title"] {
                color : black;
            }
            p:hover {
                color: yellow;
            }
            p::after {
                content: "元";
            }
        </style>
    </head>
    <body>
        <p id="title" class="red">100</p>
    </body>
</html>

其他還有組合選擇器、分組選擇器、上下文選擇器、子元素選擇器、相鄰兄弟選擇器、後續兄弟選擇器,可是這幾種更像是選擇器的組合,它們也都是由上述6種選擇器 \(\color{#FF3030}{(ID選擇器、Class選擇器、元素選擇器、屬性選擇器、僞類選擇器、僞元素選擇器)}\)組合而成,因此它們的特指度由組成它們的選擇器的特指度相加便可得到。

好比:

組合選擇符

\(\color{#FF3030}{Selector Specificity: (0, 2, 0)}\)

注意:此處是對Class屬性中同時含有red和indigo兩個值的元素進行聲明,它的特指度爲(0, 2, 0)

.red.indigo {
    color : brown;
}

分組選擇符

\(\color{#FF3030}{Selector Specificity: (0, 0, 1)}\)

注意:此處是對p、em、strong3個元素分別進行聲明,而它們3個的特指度都爲(0, 0, 1)

p , em , strong {
    color : red;
}

上下文選擇符

\(\color{#FF3030}{Selector Specificity: (0, 0, 2)}\)

注意:此處是對被包含在p元素中的em元素(\(\color{#FF3030}{此時的em元素能夠爲p元素的子孫元素}\))進行聲明,它的特指度爲(0, 0, 2)

p em {
    color : red;
}

子元素選擇符

\(\color{#FF3030}{Selector Specificity: (0, 0, 2)}\)

注意:此處是對被包含在p元素中的em元素(\(\color{#FF3030}{此時的em元素只能爲p元素的子元素}\))進行聲明,它的特指度爲(0, 0, 2)

p > em {
    color : green;
}

相鄰兄弟選擇符

\(\color{#FF3030}{Selector Specificity: (0, 0, 2)}\)

注意:此處是對與p元素擁有相同父元素的em元素(\(\color{#FF3030}{此時的em元素必須緊跟在p元素的後面}\))進行聲明,它的特指度爲(0, 0, 2)

p + em {
    color : red;
}

通常兄弟選擇符

\(\color{#FF3030}{Selector Specificity: (0, 0, 2)}\)

注意:此處是對與p元素擁有相同父元素的em元素(\(\color{#FF3030}{此時的em元素必須在p元素的後面,但不必定緊跟}\))進行聲明,它的特指度爲(0, 0, 2)

p ~ em {
    color : red;
}

特殊狀況

沒有特指度的繼承樣式

繼承樣式不考慮特指度,由下面兩個例子能說明:

<!DOCTYPE html>
<html>
    <head>
        <meta name="charset" content="utf-8"/>
        <title>繼承樣式不考慮特指度</title> 
        <style type="text/css">
            .yellow {
                color : yellow;
            }
        </style>
    </head>
    <body>
        <div class="yellow">
            <p>p標籤</p>
        </div>
    </body>
</html>

繼承樣式不考慮特指度-圖1
上述例子中p元素的color屬性值爲red(來自用戶樣式表),繼承自div元素的color屬性值yellow被覆蓋。

(\(\color{#FF3030}{注:此瀏覽器的用戶樣式表被我修改,沒有修改過的p元素的color屬性的值應該是black。}\))

<!DOCTYPE html>
<html>
    <head>
        <meta name="charset" content="utf-8"/>
        <title>繼承樣式不考慮特指度</title> 
        <style type="text/css">
            .yellow {
                color : yellow;
            }
            p {
                color : green;
            }
        </style>
    </head>
    <body>
        <div class="yellow">
            <p>p標籤</p>
        </div>
    </body>
</html>

繼承樣式不考慮特指度-圖2
上述例子中p元素的color屬性值爲green(來自元素選擇器),繼承自div元素的color屬性值yellow被覆蓋。

超脫特指度的 !important

!important是超脫特指度的存在

<!DOCTYPE html>
<html>
    <head>
        <meta name="charset" content="utf-8"/>
        <title>!important是超脫特指度的存在</title> 
        <style type="text/css">
            #id {
                color : green;
            }

            p {
                color : brown;
            }
        </style>
    </head>
    <body>
        <p id="id">p標籤</p>
    </body>
</html>

!important的特指度是最高的-圖1
修改代碼,給元素選擇器中color屬性加上!important後:

<!DOCTYPE html>
<html>
    <head>
        <meta name="charset" content="utf-8"/>
        <title>!important是超脫特指度的存在/title> 
        <style type="text/css">
            #id {
                color : green;
            }

            p {
                color : brown !important;
            }
        </style>
    </head>
    <body>
        <p id="id">p標籤</p>
    </body>
</html>

!important的特指度是最高的-圖2
元素選擇器中加了!important的聲明覆蓋了ID選擇器中沒加!important的聲明。

特指度至關時 以 後聲明的屬性爲準

當兩個選擇器的特指度至關時,特指度至關時 以 後聲明的屬性爲準。

<!DOCTYPE html>
<html>
    <head>
        <meta name="charset" content="utf-8"/>
        <title>特指度至關時 以 後聲明的屬性爲準</title> 
        <style type="text/css">
            p {
                color : green;
            }
            p {
                color : brown;
            }
        </style>
    </head>
    <body>
        <p>p標籤</p>
    </body>
</html>

在這裏插入圖片描述
後聲明的屬性覆蓋了先聲明的屬性。

總結

單個選擇器的特指度按照 !important > id選擇符 > class選擇符、屬性選擇符和僞類 > 元素選擇符和僞元素的規律排序,若是遇到組合選擇器,則按其邏輯將其拆分爲單個選擇器後相加再進行判斷。若是選擇器中的聲明包含了!important,則這條屬性會覆蓋同屬性全部不包含了!important的聲明,只有在同屬性的聲明也包含!important,而且同屬性的聲明位於的選擇器的特指度大於先前的選擇器,亦或兩個選擇器的特指度至關,但同屬性的聲明位於的選擇器位於先前的選擇器以後時,纔會覆蓋先前的選擇器的加了!important的屬性。

若是上面的話很難理解,能夠看這裏的:
第一條:比較各自所在的選擇器的特指度,特指度越大的優先級越高;
第二條:加了!important的聲明的屬性優先級最高,在都加了!important的狀況下按第一條爲準;
第三條:在特指度相等的狀況下,後聲明的優先級大於先聲明的;
第四條:優先級高的樣式覆蓋優先級低的樣式。

相關文章
相關標籤/搜索