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#titleCSS 權重 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
包含以下兩種類型
- 標籤選擇器:
p、h1 - 偽元素:
::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)