2016-11-30

CSS Selector 的優先度

一個元件同時被多個 CSS Selector 選上且其中有相同的 CSS 樣式定義時,熟勝出?
<style type="text/css">
span {
  color: red;
}

.c {
  color: blue;
}

#i {
  color: green;
}
</style>
<div>
  <span id="i" class="c">CSS</span>
</div>
上面的 CSS 字串同時被 span、.c 與 #i 選上,結果是呈現 #i 的綠色。

再看一個複雜一點的狀況。
<style type="text/css">
div span {
  color: yellow;
}

span.c {
  color: pink;
}
</style>
<div>
  <span id="i" class="c">CSS</span>
</div> 
上面的 CSS 字串同時被 div span 與 span.c 選上,結果是呈現 span.c 的粉紅色,為什麼呢?

邏輯很簡單,每個 CSS Selector  都有一個「優先度」,可以用「數值」來表示。

標籤選擇器,像是 div 或者 span,得 1 分。

類別選擇器,就是 class 定義的名稱,得 10 分。

ID 選擇器,就是 id 定義的名稱,得 100 分。

還有行內選擇器(Inline selector),就是用 style="..." 直接寫在標籤裡的,得 1000 分。

最終以得方最高的選擇器勝出。

上面第一個範例,span 為標籤選擇器,得 1 分,.c 為類別選擇器,得 10 分,#i 為 ID 選擇器,得 100 分,所以 #i 勝出。

第二個範例,div span 等於兩個標籤選擇器(各 1 分),得 2 分,span.c 為一個標籤選擇器(1 分)加上一個類別選擇器(10 分),得 11 分。

另外還有兩個特別的選擇器,擬元素(像是 :first-line)與標籤選擇器相同,得 1 分,擬類別(像是 :hover)與類別選擇器相同,得 10 分。

事實上,上面第二個範例的 div span 稱為後裔選擇器,是由所有列出的選擇器加總而成。

那繼承而來的屬性呢?
<style type="text/css">
span {
  color: red;
}

#i {
  color: green;
}
</style>
<div id="i">
  <span>CSS</span>
</div>
CSS 字串的 color 屬性有兩個來源,第一個是從 div 的 ID 選擇器繼承來的綠色,以及本身 span 標籤選擇器的紅色,會是呈現來自 100 分的 ID 選擇器的綠色?不,是呈現 span 標籤選擇器的紅色。

繼承的屬性只有在元件本身沒有任何選擇器符合時才會套用,沒有任何優先度可言。

最後,當優先度相同時會怎辦?
<style type="text/css">
.d span {
  color: red;
}

div .s {
  color: yellow;
}
</style>
<div class="d">
  <span class="s">CSS</span>
</div>
.d span 與 div .s 的優先度都是 11 分,當優先度相同時勝出的是「最後定義」的 div .s 選擇器

「最後定義」指的是檔案中最後出現的,這其中包括使用 link 帶入的外部樣式檔,以及使用 style 定義的內部樣式表。
<link rel="stylesheet" href="a.css">
<style type="text/css">
...
</style>
以上範例的內部樣式表(style)優於外部樣式檔(link)。

但是如果位置對調。
<style type="text/css">
...
</style>
<link rel="stylesheet" href="a.css"> 
就變成外部樣式檔(link)優於內部樣式表(style)。-

內部樣式表(style)與外部樣式檔(link)中相同的優先度最終以「位置」決定。

一般的慣例是先列出所有的外部樣式檔(link),然後才是內部樣式表(style)。
---
---
---

沒有留言:

張貼留言