CSS樣式層疊權重值
根據CSS規範,具體性越明確的樣式規則,權重值越高。計算權重值的依據,並不是許多文章所描述的那樣“class是10,標籤是1,ID是100”之類——雖然這樣在大多數情況下能夠得到正確的結果。
首先來看一個便於記憶的順序”important>內聯 >ID>類 >標籤 |偽類|屬性選擇 >偽對象 >繼承 >萬用字元”
選取器權重值的計算
A:如果規則是寫在標籤的style屬性中(內聯樣式),則A=1,否則,A=0. 對於內聯樣式,由於沒有選取器,所以B、C、D的值都為0,即A=1, B=0, C=0, D=0(簡寫為1,0,0,0,下同)。
B:計算該選取器中ID的數量。如果有則B=1,沒有B=0(例如,#header 這樣的選取器,計算為0, 1, 0, 0)。
C:計算該選取器中偽類及其它屬性的數量(包括class、屬性選取器等,不包括虛擬元素)。(例如, .logo[id='site-logo'] 這樣的選取器,計算為0, 0, 2, 0)(後面將進一解釋為什麼會是0,0,2,0)。
D:計算該選取器中虛擬元素及標籤的數量。(例如,p:first-letter 這樣的選取器,計算為0, 0, 0, 2)。
CSS2規範中給出的一些例子:
- * {} /* 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 */
這種說法是錯誤的:
根據這樣的定義,所以很多文章簡單地把規則歸納為:內聯樣式的權重值是1000,ID選取器的權重值是100,class選取器的權重值是10,標籤選取器的權重值是1. 整條規則中的所有選取器權重值相加得到整個樣式規則的權重值,數字越大權重值越高。
大多數情況下,按照這樣的理解得出的結論沒有問題,但是遇到下面這樣的情況就出現問題了:
樣式一:body header div nav ul li div p a span em {color: red}
樣式二:.count {color: blue}
按照錯誤的計算方法,樣式一的權重值是11,樣式二的權重值是10,如果這兩條規則用於同一個元素,則該元素應該是紅色。實際結果卻是藍色。
權重值的比較
按照四組計算的正確方法,上面例子中的樣式一權重值應該是0, 0, 0, 11,樣式二的權重值是0, 0, 1, 0。
根據規範,計算權重值時,A,B,C,D四組值,從左至右,分組比較,如果A相同,比較B,如果B相同,比較C,如果C相同,比較D,如果D相同,後定義的優先。
樣式二和樣式一的A、B相同,而樣式二的C大於樣式一,所以,不管D的值如何,樣式二權重值都大於樣式一。這就是正確的答案。
特殊的 !important
在按照ABCD四組計算比較之外,在定義樣式的時候,還可以對某一個屬性應用 !important。對於一直從事編程而沒做過重構的人,需要特別注意的是這裡的“!”與其在程式設計語言中的意義剛好相反,不是代表“不重要”而是代表“很重要”。
CSS2規範中規定:!important 用於單獨指定某條樣式中的單個屬性。對於被指定的屬性,有 !important 指定的權重值大於所有未用 !important 指定的規則。
例如:
樣式一: #header nav ul li.current {color: red; font-weight: bold;}
樣式二: li:hover {color: blue !important; font-weight: normal;}
就整條規則而言,樣式一的權重值為 0, 1, 1, 3,而樣式二的權重值僅為0, 0, 2, 0。所以應用於相同元素時,應該樣式一生效。但是對於color這個屬性,由於在樣式二中用 !important 做了指定,因此color將應用樣式二的規則。而font-weight則按照規定用樣式一的規則。
如果多條規則中都對同一個屬性指定了 !important 呢?這時候 !important 的作用相互抵銷,依然按照ABCD四組計算比較。
因此 !important 的作用只有在具有唯一性時才能提現,但是我們永遠無法預料自己什麼時候又需要覆蓋一個已經指定了 !important 的屬性,所以最好的辦法就是:不要使用 !important。