這篇博客在在兩臺電腦上分別完成的,故而有些截圖是Firefox,有些是Chrome,有些改動了瀏覽器的用戶樣式表,有些沒改,但不會影響閱讀,特此說明,勿怪。css
css選擇器決定css樣式能渲染到對應的元素上。html
元素選擇器:
瀏覽器
Class選擇器:
ID選擇器:
spa
瀏覽器在處理單獨的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計算公式,常常看到這樣的說法(這是錯誤的):繼承
!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選擇器的數量再多,也是無效的。
選擇器共有:
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>
上述例子中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>
上述例子中p元素的color屬性值爲green(來自元素選擇器),繼承自div元素的color屬性值yellow被覆蓋。
!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>
修改代碼,給元素選擇器中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的聲明覆蓋了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的狀況下按第一條爲準;
第三條:在特指度相等的狀況下,後聲明的優先級大於先聲明的;
第四條:優先級高的樣式覆蓋優先級低的樣式。