CSS 選擇器的優先順序 ( 權重 )
如果當 CSS 選擇器選取元素時,發生「多個選擇器選擇到同一個元素」的狀況,就會根據「權重 Specificity」來判斷這個元素套用樣式的「優先順序」,這篇教學將介紹 CSS 選擇器裡最重要的觀念:權重 Specificity。
快速導覽:
選擇器的權重計算方式
CSS 選擇器會按照「A,B,C」的計算方式判斷權重,只要出現了對應的選擇器,所對應的 A、B、C 數值就會增加 1,各種選擇器對應的數值如下表所示:
參考 W3C 官方:Calculating a selector’s specificity
選擇器 | 權重 | 數字表示 |
---|---|---|
ID | A=1 | 1,0,0 |
Class 類別 | B=1 | 0,1,0 |
Attribute 屬性 | B=1 | 0,1,0 |
虛擬類別 | B=1 | 0,1,0 |
元素 | C=1 | 0,0,1 |
虛擬元素 | C=1 | 0,0,1 |
通用選擇器 * | 最低 | 0,0,0 |
「A,B,C」的權重大小為「A>B>C」,因此只要「越左側的數值越大,權重就越高」,套用樣式時也就會套用這個選擇器的樣式,以下方的 CSS 為例,因為 ID 選擇器的權重較高,所以會套用 id 選器器的紅色,而不會套用元素選擇器的藍色。
/* HTML 使用:<h1 id="title">OXXO.STUDIO</h1> */
#title {color: red;} /* 權重:1,0,0 */
h1 {color: blue;} /* 權重:0,0,1 */
然而,選擇器的權重具有「疊加」的特性,這對於具有「結構選擇器」特別明顯,因為結構選擇器會使用「多個選擇器組成結構」,結構中每個選擇器都有各自權重的數值,疊加的數值越多,權重也就越高,下方 CSS 展示不同結構選擇器所疊加的權重 ( 由小到大 ):
選擇器 | 權重數值 | 說明 |
---|---|---|
* |
0,0,0 | 通用x1 |
li |
0,0,1 | 元素x1 |
ul li |
0,0,2 | 元素x2 |
ul li span |
0,0,3 | 元素x3 |
h1 + *[rel] |
0,1,1 | 屬性x1 |
ul li span.red |
0,1,3 | 類別x1 |
li .red.level |
0,2,1 | 類別x2 |
#oxxo |
1,0,0 | idx1 |
#oxxo::before() |
1,0,1 | idx1、虛擬元素x1 |
#oxxo *:not(nav) li |
1,0,2 | idx1、元素x2 |
.oxxo :is(.ok, #cool) |
1,1,0 | 類別x1,is() 取出最高的權重為 idx1 |
html body table#oxxo tr[name] td |
1,1,5 | idx1、元素x5、屬性x1 |
順序對權重的影響
如果是「相同權重」的選擇器,則會按照「執行的順序」決定權重,後方選擇器的會覆蓋前方選擇器裡相同的樣式,以下方的 CSS 為例,當順序不同時,呈現的文字顏色就會不同。
HTML:
<div class="apple"><span name="oxxo">我是什麼顏色呢?</span></div>
下方的 CSS 執行後會出現「藍色」文字。
div span[name] {color: red;} /* 權重:0,1,2 */
div.apple span {color: blue;} /* 權重:0,1,2,因為在後方所以呈現藍色 */
下方的 CSS 執行後會出現「紅色」文字。
div.apple span {color: blue;} /* 權重:0,1,2 */
div span[name] {color: red;} /* 權重:0,1,2,因為在後方所以呈現紅色 */
inline 行內樣式的權重
如果 HTML 的元素使用了「行內樣式 inline style」,這個元素的權重就會變成「最高」( 類似 1,0,0,0 的概念 ),只有使用宣告「!important」的樣式才能覆蓋,以下方的 HTML 為例,當 h1 裡加入了行內樣式,就算使用了 ID 選擇器,仍然無法套用 ID 選擇器的樣式。
<!-- HTML 程式碼 -->
<h1 id="name" style="color:red">OXXO.STUDIO</h1>
<!-- CSS 程式碼 -->
<style>
#name {color: blue;}
<style>
!important 對權重的影響
「!important
」在選擇器中是一個特別的宣告,只要選擇器裡的某個「樣式」出現了 !important
宣告,該「樣式」的權重就會變成「最高」,除非有另外選擇器裡的樣式也使用了 !important
,才會再按照相關的規則進行權重計算,寫法如下:
選擇器 {color: red!important;} /* 擺在屬性值的後方,分號的前方 */
使用 !important
需注意下列幾個重點:
!important
並沒有特別的權重值 ( 因為是針對樣式 ),主要目的在於排解一些選擇器裡樣式宣告發生衝突的狀況,常用於處理「覆蓋第三方套件樣式」使用。- 使用
!important
常會造成樣式不易管理或權重錯亂的狀況,因此一份好的 CSS 樣式表,請避免使用!important
。
下方的範例同時使用 !important
、行內樣式和 ID 選擇器、元素選擇器,屬於「不好且容易錯亂」的撰寫方式,相當不建議使用,最終呈現結果的規則如下:
- 1、h1 被行內樣式影響,呈現紅色文字。
- 2、ID 選擇器使用了
color: blue!important;
,改為呈現藍色文字。- 3、ID 選擇器裡的其他樣式因為沒有使用
!important
會按照權重規則計算,呈現行內樣式的黃色背景。- 4、h1 選擇器雖然也使用
color: green!important
,但權重較小,就不會套用顏色樣式。- 5、最後使用 ID 選擇器裡
!important
的藍色文字、行內樣式的黃色背景。
<!-- HTML 程式碼 -->
<h1 id="name" style="color:red; background:#ff0;">OXXO.STUDIO</h1>
<!-- CSS 程式碼 -->
<style>
#name {
color: blue!important;
background: #f00;
font-size: 50px;
}
h1 {
color: green!important; /* 因為 h1 權重比 #name 小,會套用 #name 裡的樣式 */
}
</style>
小結
CSS 選擇器的優先順序 ( 權重 ) 是學習 CSS 最重要的觀念 ( 沒有之一 ),許多初學者和開發者,時常因為搞不清楚權重,而撰寫大量又互相覆蓋的 CSS,造成管理不易且容易出錯,透過這篇教學,相信應該能幫助大家清楚掌握 CSS 選擇器的權重用法!
意見回饋
如果有任何建議或問題,可傳送「意見表單」給我,謝謝~