筆記-CSS選擇器的套用優先順序
3 | 29,592 |
寫Web的人或多或少對CSS有一些了解,知道CSS Selector(如#id, .className, div.className)在套用上會採取愈具針對性愈優先的原則,所以當多組Style設定衝突時,指定#id比指定.className優先,指定.className的規則又比只指定div優先。用個具體例子來說明,以下<div>中的文字是什麼顏色?
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>CSS Specificity</title>
<style type="text/css">
#d { color: Orange }
.clsName { color: Yellow }
div { color: Green }
</style>
</head>
<body>
<div id="d" class="clsName" style="color: Red">Text</div>
</body>
</html>
因為 element style > #d > .clsName > div,所以由style=”color: Red”勝出,文字是紅色的。若將style="color: Red”移除,則由#d做主變成橘色;將#d規則移除後換.clsName當家變成黃色;把.clsName也拿掉,才輪到div決定綠色。
這是比較簡單的例子。那如果是下面的情況呢?
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>CSS Specificity</title>
<style type="text/css">
#d1 { color: Blue }
div#d1 { color: Red }
#d1.clsName { color: Orange }
div.clsName { color: Green }
span .c3 { color: Red }
.c1 span { color: Green }
.c2 span { color: Purple }
span span.c3 { color: Blue }
</style>
</head>
<body>
<div id="d1" class="clsName">不算難</div>
<span id="d2" class="c1 c2">
<span id="d3" class="c3">好機車</span>
</span>
</body>
</html>
"不算難"還好猜,可推測 #d1.clasName > div#d1 > #d1,所以是橘色。但"好機車"的藍色要怎麼推算出來?
在W3C的CSS 2.1規格中定義了Selector的a-b-c-d套用法則(術語叫Selector’s Specificity):
- count 1 if the declaration is from is a 'style' attribute rather than a rule with a selector, 0 otherwise (= a) (In HTML, values of an element's "style" attribute are style sheet rules. These rules have no selectors, so a=1, b=0, c=0, and d=0.)
- count the number of ID attributes in the selector (= b)
- count the number of other attributes and pseudo-classes in the selector (= c)
- count the number of element names and pseudo-elements in the selector (= d)
W3C的文件還附上了詳細的範例(節錄於下),應該不難理解:
* {} /* 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 */
比較順序時,先比a,a大的勝出;若a相同再比較b,以此類推。(規格原文說in a number system with a large base,可以想像成a * 1000^3 + b * 1000^2 + c * 1000 + d)
回到好機車的例子:
span .c3 { color: Red } => a=0 b=0 c=1 d=1
.c1 span { colro: Green } => a=0 b=0 c=1 d=1
.c2 span { color: Purple } => a=0 b=0 c=1 d=1
span span.c3 { color: Blue } => a=0 b=0 c=1 d=2
這解釋了為什麼最後由span span.c3決定藍色。但值得注意的是,span .c3、.c1 span、.c2 span都是c=1, d=1,若由這三者對決,.c1/.c2會優於span,而.c2比.c1晚出現,最後將會由.c2 span封王--紫色。,三者優先權相同,以後出現者為準,本例為紫色,若將 span .c3 移到最下方則會是紅色。
Comments
# by 阿呆
span .c2、.c1 span、.c2 span都是c=1, d=1,若由這三者對決,.c1/.c2會優於span,而.c2比.c1晚出現,最後將會由.c2 span封王--紫色 -------------------------------------------------- .c1/.c2會優於span <- 這句是錯的,三者的優先權都一樣,就看誰最後出現,就採用那種設定.所以說,如果span .c3 { color: Red } 寫在最後,就會是紅色
# by Jeffrey
to 阿呆,你是對的,span .c3 與 .c2 span 優先權相同,以後出現者為準,已修正本文。感謝指正。
# by fruitbear
真的好機車(笑)