筆記-CSS選擇器的套用優先順序

寫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 移到最下方則會是紅色。

歡迎推文分享:
Published 08 June 2011 07:52 AM 由 Jeffrey
Filed under:
Views: 23,093



意見

# 阿呆 said on 16 July, 2017 04:25 AM

span .c2、.c1 span、.c2 span都是c=1, d=1,若由這三者對決,.c1/.c2會優於span,而.c2比.c1晚出現,最後將會由.c2 span封王--紫色

--------------------------------------------------

.c1/.c2會優於span <- 這句是錯的,三者的優先權都一樣,就看誰最後出現,就採用那種設定.所以說,如果span .c3 { color: Red } 寫在最後,就會是紅色

# Jeffrey said on 16 July, 2017 08:17 PM

to 阿呆,你是對的,span .c3 與 .c2 span 優先權相同,以後出現者為準,已修正本文。感謝指正。

你的看法呢?

(必要的) 
(必要的) 
(選擇性的)
(必要的) 
(提醒: 因快取機制,您的留言幾分鐘後才會顯示在網站,請耐心稍候)

5 + 3 =

搜尋

Go

<June 2011>
SunMonTueWedThuFriSat
2930311234
567891011
12131415161718
19202122232425
262728293012
3456789
 
RSS
創用 CC 授權條款
【廣告】
twMVC
最新回應

Tags 分類檢視
關於作者

一個醉心技術又酷愛分享的Coding魔人,十年的IT職場生涯,寫過系統、管過專案, 也帶過團隊,最後還是無怨無悔地選擇了技術鑽研這條路,近年來則以做一個"有為的中年人"自許。

文章典藏
其他功能

這個部落格


Syndication