在本書的[2.3.1 (X)HTML與浏覽器內置樣式]一節曾經介紹過,樣式表可能有三個不同的來源:制作者、用戶和浏覽器。這三個來源的樣式表可能在范圍上有重疊,它們根據層疊規則互相作用。
4.6.1 層疊的順序
CSS的層疊對每一個樣式規則指定一個權重。如果要應用若干個規則,那麼權重最大的那個規則具有優先權。層疊規則依據下面幾個步驟進行:
1. 查找有沖突的元素
浏覽器會找到那些存在疑問的元素和屬性的聲明,如果相關聯的選擇器匹配存在疑問的元素,則聲明適用。
2. 樣式表的來源
按照規則的重要性(普通或者重要)和來源(用戶、制作者或者浏覽器)來從低到高排序:
1) 浏覽器的缺省樣式;
2) 用戶定義的普通樣式;
3) 制作者定義的普通樣式;
4) 制作者定義的重要性(“!important”聲明)樣式;
5) 用戶定義的重要性(“!important”聲明)樣式。
提示:重要性(“!important”聲明),請參見本書[4.6.4 重要性]一節。
對於制作者定義的外部CSS文件引入的規則,它們的權重取決於它們引入的順序。例如:
<link rel="stylesheet" href="basic.css" type="text/css" media="all" />
<link rel="stylesheet" href="font.css" type="text/css" media="all" />
則font.css中的定義高於basic.css中的定義。
對於在樣式表中使用@import規則引入的其他樣式表,優先級規則同樣適用。
嵌入式樣式表的規則高於從文件引入的樣式規則。行內樣式表則又高於嵌入式樣式表。
3. 選擇器的特殊性
聲明的第2排序基於選擇器的特殊性:特殊的選擇器超越一般的選擇器。偽元素和偽類分別被視為一般元素和一般類。
4. 規則出現的先後次序
最後,根據規則出現的先後次序來排列。如果兩條規則具有相同的權重,相同的來源和相同的特殊性,則後出現的規則超越先出現的規則。
引入的樣式表中的規則被認為出現在樣式表本身的所有規則之前。
除了個別聲明的“!important”指定,上述策略給予制作者的樣式表比用戶樣式表更大的權重。
4.6.2特殊性的計算 既然有層疊的規則,那麼,如果有如下代碼,其在浏覽器內會如何顯示呢?
.warning { color: red; }
p { color: green; }
<p class=”warning”>層疊和繼承的規則如何實現?</p>
此代碼在浏覽器內顯示如圖4-31所示。
圖4-31 選擇器的特殊性
這是由於類選擇器“warning”和類型選擇器“p”的“特殊性”不同。
特殊性(specificity)描述了不同選擇器的相對權重(weight)。一個選擇器的特殊性是這樣計算的:
·如果CSS屬性是通過(X)HTML元素的style屬性定義的,則記為a=1,否則記為0;
由於style屬性是寫在(X)HTML標簽內的,因此不存在選擇器,所以:a=1, b=0, c=0, 且 d=0;
·計算選擇器中ID選擇器的數量,計為b;
·計算選擇器中類選擇器、屬性選擇器和偽類的數量,計為c;
·計算選擇器中類型選擇器的數量,計為d;
·忽略偽元素。
將這4個數字(a, b, c, d)相連(數字進制要以大的為准),得到特殊性。例如:
{ …… } 特殊性 = 0, 0, 0, 0
li { …… } 特殊性 = 0, 0, 0, 1
ul li { …… } 特殊性 = 0, 0, 0, 2
ul ol+li { …… } 特殊性 = 0, 0, 0, 3
h1 + [rel="up"] { …… } 特殊性 = 0, 0, 1, 1
ul ol li.warning { …… } 特殊性 = 0, 0, 1, 3
li.menu.level { …… } 特殊性 = 0, 0, 2, 1
#x34y { …… } 特殊性 = 0, 1, 0, 0
<p styel=”……”> 特殊性 = 1, 0, 0, 0
特殊性高的規則會取代特殊性低的規則,無論其書寫的先後順序如何,例如:
h1 {color red;} 0,0,0,1
body h1 {color green;} 0,0,0,2 (勝出)
或者:
h2.grape {color purple;} 0,0,1,1 (勝出)
h2 {color silver;} 0,0,0,1
4.6.3 繼承和特殊性 在特殊性的框架下,繼承的特殊性為“0”。也就是說,任何顯式的規則聲明都會覆蓋掉繼承的樣式,例如有如下代碼:
em { color: blue; }
p.list { color: gray; }
<p class="list">繼承的特殊性為<em>“0”</em>。</p>
雖然“p.list”的特殊性為“0, 0, 1, 1”,但是,對“em”的color聲明還是會覆蓋掉從“p.list”繼承的color樣式,因此在浏覽器內顯示如圖4-32所示。
圖4-32 繼承與特殊型
因此,如果需要讓p內的em能呈現和p一樣的顏色,則需要如下定義:
p.list,
p.list em { color gray; }
4.6.4 重要性 雖然層疊和特殊性決定了CSS規則的最後應用效果,但是,也可以通過聲明某個規則的“重要性”來提高此規則的權重,例如圖4-33所示。
圖4-33 重要性的表現
雖然ID選擇器的特殊性高於類型選擇器,但是由於類型選擇器(div)屬性值後面添加了“!important”重要性聲明,因此“color : red”這條聲明的特殊性最高。
“!important”重要性聲明的權重甚至高於內聯式樣式,例如有如下代碼,其在浏覽器內顯示如圖4-34所示。
div { color: red !important; }
<div style="color: blue;">設定了style的div</div>
圖4-34 重要性的權重高於內嵌式樣式
在CSS 1中,制作者的“!important”規則超越用戶的“!important”規則。但是在CSS 2中,用戶的“! important”規則具有最高的優先級,這樣可以讓網頁更具易用性,例如有些視力不好的用戶,可能會設定比較大的字體,這樣就可以防止制作者定義了過 小的字體而使用戶閱讀困難。
4.6.5 非CSS的表現類內容 現在仍然有一些制作者在(X)HTML文檔內插入一些表現類的內容,例如<font>標簽和align屬性,這些表現類的內容被認為具有0特殊性,並且被當作是插入在作者樣式表的開頭部分,因此可能會被後面定義的樣式規則覆蓋。
例如下列代碼在浏覽器內顯示如圖4-35所示。
p {
background: yellow;
text-align: left;
}
<p align="right"><p align="right">,CSS:text-align: left;</p>
圖4-35 重要性的權重高於內嵌式樣式
由4-35讀者可以看到,雖然<p>的align屬性定義為“right”,即右對齊,但是由於CSS中定義了“text-align: left;”,因此文字還是左對齊顯示。
但是,如果是下面的代碼:
.test { color: green; }
<p class="test">p內的示例<font color="blue">文字</font>。</p>
則<font>內的文字依然是藍色(blue),因為對於<font>,<p>的color屬於繼承,因此標簽內的屬性高於繼承值,但是如果增加CSS規則:
font { color: red; }
則<font>內的文字會變為紅色(red),即“color="blue"”被CSS的“color: red; ”覆蓋。