優先權

假設您使用的是以下 HTML 和 CSS:

<button class="branding">Hello, Specificity!</button>
.branding {
  color: blue;
}

button {
  color: red;
}

這裡有兩項規則會指定相同的元素。每項規則都包含要設定按鈕顏色的宣告:一個嘗試將按鈕設為紅色,另一個則嘗試將按鈕設為藍色。哪個宣告會套用至元素?

瞭解 CSS 特殊性演算法,是理解 CSS 如何在競爭宣告之間做出決定的關鍵。

特定性是分層處理的其中一個階段,我們在上一單元介紹了分層處理

特異性評分

系統會為來源中的每個選取器規則評分。您可以將特定性視為總分,而每個選取器類型都會為該分數賺取積分。宣告會以最具體的規則為準。

在實際專案中,您必須取得平衡,確保您要套用的 CSS 規則確實「套用」,同時盡量維持低分數以避免複雜性。特異性應只設為所需程度,而非盡可能設為最高。日後,您可能需要套用一些更重要的 CSS。如果您追求最高的專一性,就會讓這項工作變得困難。

優先權不是小數,而是由 ABC 三個元件組成的三重奏。

  • A:類似 ID 的特定性
  • B:類別式特異性
  • C:元素類型特定性

通常會使用 (A,B,C) 符號表示。例如:(1,0,2)。您也可以使用 A-B-C 做為替代符號。

這張圖表顯示特異性的三個要素 (A、B、C)。每個元件都會在圖表中顯示其代表意義,以及影響該元件的選取器範例。
圖表說明各種選取器會影響哪些特定元件。

比較特徵

系統會依序比較三個組件,藉此比較特異性:A 值越大,特異性越高;如果兩個 A 值相同,則 B 值越大,特異性越高;如果兩個 B 值也相同,則 C 值越大,特異性越高;如果所有值都相同,則兩個特異性相同。

舉例來說,(1,0,0) 的專一性高於 (0,4,3),因為 (1,0,0) 中的 A 值 (即 1) 大於 (0,4,3) 中的 A 值 (即 0)。

選取器會影響特異性

特徵三元組中的每個部分開頭都會以 0 的值開始,因此預設特徵為 (0,0,0)。選取器的每個部分都會增加特定性,並根據選取器類型增加 ABC 的值。

通用選取器

通用選取器 (*) 不會新增任何特異性,其值會維持在 (0,0,0) 的初始特異性。

* {
  color: red;
}

元素或擬元素選取器

元素 (類型) 或擬元素選取器會新增類似元素的特定性,將 C 元件增加 1

以下範例的整體特異性為 (0,0,1)

類型選取器

div {
  color: red;
}

擬造元素選取器

::selection {
  color: red;
}

類別、擬似類別或屬性選取器

類別擬類別屬性選取器會新增類別類型特徵,將 B 元件增加 1

以下範例的特異性為 (0,1,0)

類別選取器

.my-class {
  color: red;
}

擬造類別選取器

:hover {
  color: red;
}

屬性選取器

[href='#'] {
  color: red;
}

ID 選取器

ID 選取器會新增 類似 ID 的特定性,只要您使用 ID 選取器 (#myID) 而非屬性選取器 ([id="myID"]),即可將 A 元件增加 1。

在以下範例中,特異性為 (1,0,0)

#myID {
  color: red;
}

其他選取器

CSS 有許多選取器。但並非所有字詞都會增加具體性。舉例來說,:not() 擬物類別本身不會為特徵計算提供任何資訊。

不過,傳入做為引數的選取器會加入到特異性計算中。

div:not(.my-class) {
  color: red;
}

這個範例的特定性為 (0,1,1),因為它有一個類型選取器 (div) 和一個 :not() 內部的類別。

進行隨堂測驗

測驗您對特定性評分機制的相關知識

a[href="#"] 的專一性為何?

(0,1,0)
(0,0,1)
(0,1,1)

不會影響特異性的因素

以下是一些常見的迷思,關於影響特異性的因素。

內嵌樣式屬性

直接套用至元素 style 屬性的 CSS 不會影響特徵,因為這是級聯中會在特徵之前評估的不同步驟。

<div style="color: red"></div>

如要在樣式表單中覆寫此宣告,您必須在連鎖的早期步驟中使用宣告勝出。

舉例來說,您可以將 !important 新增至其中,讓該檔案成為已授權的 !important 來源的一部分。

!important 宣告

CSS 宣告結尾的 !important 不會影響特異性,但會將宣告放入不同的來源,也就是已著作權人 !important

在以下範例中,.my-class 的特定性與 !important 宣告的勝出無關。

.my-class {
  color: red !important;
  color: white;
}

如果兩個宣告都是 !important,則又會再次使用特異性,因為級聯的來源步驟尚未能判斷勝出者。

.branding {
  color: blue !important;
}

button {
  color: red !important;
}

特定內容

使用複雜或複合選取器時,該選取器的每個部分都會增加特異性。請參考以下 HTML 範例:

<a class="my-class another-class" href="#">A link</a>

這個連結包含兩個類別。以下 CSS 中的規則具有 (0,0,1) 的特定性

a {
  color: red;
}

如果您在選取器中參照其中一個類別,現在該類別具有(0,1,1)的特定性:

a.my-class {
  color: green;
}

將其他類別新增至選取器,現在它具有 (0,2,1) 的特定性

a.my-class.another-class {
  color: rebeccapurple;
}

在選取器中加入 href 屬性,現在的特定性為 (0,3,1)

a.my-class.another-class[href] {
  color: goldenrod;
}

最後,將 :hover 擬造類別新增至所有這些,選取器最終會以 (0,4,1) 的特定性結尾:

a.my-class.another-class[href]:hover {
  color: lightgrey;
}

進行隨堂測驗

測驗您對特定性評分機制的相關知識

下列哪個選取器的特定性為 (0,2,1)

article:hover a[href]
article.card.dark
article > section

務實提高精確度

假設您有以下 CSS:

.my-button {
  background: blue;
}

button[onclick] {
  background: grey;
}

使用以下 HTML 程式碼:

<button class="my-button" onclick="alert('hello')">Click me</button>

按鈕的背景為灰色,因為第二個選取器的特定性為 (0,1,1)。這是因為它有一個類型選取器 (button),即 (0,0,1),以及一個屬性選取器 ([onclick]),即 (0,1,0)

先前的規則 .my-button 等於 (0,1,0),因為它有一個類別選取器,比 (0,1,1) 的明確性低。

如要強化此規則,您可以重複類別選取器,如下所示:

.my-button.my-button {
  background: blue;
}

button[onclick] {
  background: grey;
}

由於新選取器會取得特定性 (0,2,0),因此按鈕現在會顯示藍色背景。

若特定性相同,則會改為使用級聯程序中的下一個步驟

我們先繼續使用按鈕範例,並將 CSS 切換為以下內容:

.my-button {
  background: blue;
}

[onclick] {
  background: grey;
}

按鈕的背景為灰色,因為兩個選取器的特異性相同,都是 (0,1,0)

如果您切換來源順序中的規則,按鈕就會變成藍色。

[onclick] {
  background: grey;
}

.my-button {
  background: blue;
}

這是因為兩個選取器的特異性相同。在這種情況下,層疊會改為使用顯示順序步驟

資源