Skip to content

2025-12-16

/ 9 分鐘閱讀

CSS 選擇器權重 | Specificity

此文章是 FrontendMaster 上的 Advanced Web Development Quiz 課程筆記

問題

Order the CSS selectors by specificity (highest to lowest)

Select answers in the correct order.

[1] div h1.large-text::before
[2] div h1:first-child
[3] h1:not(.small-test)
[4] .large-text:nth-child(1)
[5] h1.large-text[id="title"]
[6] h1.large-text#title

CSS 權重 CSS Specificity

Specificity 是瀏覽器的一套演算法,透過這個做法來計算 DOM 元素最終該套用哪個樣式呈現在畫面上。

深入瞭解它的概念,更有能力寫出好維護的 CSS

權重

CSS 透過選擇器來指定符合條件的元素(或偽元素)該套用的 CSS 屬性,而這些選擇器上所定義的權重類別數量則是決定權重的關鍵,當有不同的屬性宣告在同一個元素上,則最後就會由權重較高的選擇器套用樣式在該元素上。

這一套計算權重的演算法可以想像是四欄的值,權重由大至小分別是:inline-style、ID、CLASS、TYPE,該值代表選擇器中出現對應類型的次數

inline-style

  • inline-style 出現時(例如:style="font-size: 3rem"),此時這個權重就是 1-0-0-0
  • 唯一能覆蓋這個樣式的方法就是 !important

ID

當出現 ID 選擇器時,每一個 ID 的權重值加上 0-1-0-0

CLASS

當出現 CLASS 選擇器時,每一個 CLASS 的權重值加上 0-0-1-0

包含以下三種類型

  • .any-class
  • 屬性選擇器:[type="input"]
  • 偽類別::hover:nth-of-type(3n)

TYPE

當出現 TYPE 類型的選擇器,每一個 TYPE 權重值加上 0-0-0-1

包含以下兩種類型

  • 標籤選擇器:ph1
  • 偽元素:::before::placeholder 和其他有雙冒號的選擇器

沒有權重

  • *:where() 這種與其參數不會納入計算
  • 關係選擇器(CSS combinators):+>~" "||
  • :is():has():not() 這種類型的選擇器本身並不會增加權重,但是他的參數反而會計算權重

實例

css
[type='input'] {
    /* 0-0-1-0 */
    color: black;
}

input:focus {
    /* 0-0-1-1 */
    color: blue;
}

#form input.form-field {
    /* 0-1-1-1 */
    color: green;
}

假設以上都可以選擇到某一個 <input>,在比較的時候,權重會從左到右一一比較,如果某一個選擇器「先」在某一欄勝出了,那麼將會套用該選擇器內宣告的屬性,如果同一欄平手,那就往右邊的下一欄比較,假如最後沒能找到勝者,那麼最後就會比較哪一段在 CSS 中寫在比較後面

<input> 顯示的文字顏色應是綠色

:where()

補充說明一下這個讚讚的東西,用了這個就可以用 ID (或其他選擇器) 精確的指定某個元素,而不會讓他的權重很高,對於開發第三方插件的開發者,如果使用這個選擇器,插件的使用者就可以輕易地蓋過已經設定的樣式。

css
/* 第三方套件 */
:where(#widget-container) a {
    /* 0-0-0-1 */
}

/* 套件使用者 */
a {
    /* 0-0-0-1 */
}

layer

如果有使用第三方插件時,使用者也可以主動透過 layer 降低該插件內宣告的樣式權重。如下,在 CSS 引入的尾巴加上 layer(),就能讓所有後面使用者定義的 CSS 內容一定會高過於第三方插件內的任何已定義的樣式。

css
@import "third-party.css" layer();

p,
p * {
  font-size: 1rem;
}

答案

[6] h1.large-text#title
[5] h1.large-text[id="title"]
[4] .large-text:nth-child(1)
[1] div h1.large-text::before
[2] div h1:first-child
[3] h1:not(.small-test)

參考

最後更新時間:

0 %
MIT Licensed | Copyright © 2025-present Wen-Hsiu's Blog