搜尋

CSS 選擇器的優先順序 ( 權重 )

如果當 CSS 選擇器選取元素時,發生「多個選擇器選擇到同一個元素」的狀況,就會根據「權重 Specificity」來判斷這個元素套用樣式的「優先順序」,這篇教學將介紹 CSS 選擇器裡最重要的觀念:權重 Specificity。

快速導覽:

CSS 教學 - CSS 選擇器的優先順序 ( 權重 )

選擇器的權重計算方式

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 教學 - CSS 選擇器的優先順序 ( 權重 ) - 順序對權重的影響

下方的 CSS 執行後會出現「紅色」文字。

div.apple span {color: blue;}  /* 權重:0,1,2 */
div span[name] {color: red;}   /* 權重:0,1,2,因為在後方所以呈現紅色 */

CSS 教學 - CSS 選擇器的優先順序 ( 權重 ) - 相同權重怎麼辦?

inline 行內樣式的權重

如果 HTML 的元素使用了「行內樣式 inline style」,這個元素的權重就會變成「最高」( 類似 1,0,0,0 的概念 ),只有使用宣告「!important」的樣式才能覆蓋,以下方的 HTML 為例,當 h1 裡加入了行內樣式,就算使用了 ID 選擇器,仍然無法套用 ID 選擇器的樣式。

參考:HTML 套用 CSS 樣式

<!-- HTML 程式碼 -->
<h1 id="name" style="color:red">OXXO.STUDIO</h1>

<!-- CSS 程式碼 -->
<style>
  #name {color: blue;}
<style>

CSS 教學 - CSS 選擇器的優先順序 ( 權重 ) - inline 行內樣式的權重

!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 選擇器的優先順序 ( 權重 ) - !important 對權重的影響

小結

CSS 選擇器的優先順序 ( 權重 ) 是學習 CSS 最重要的觀念 ( 沒有之一 ),許多初學者和開發者,時常因為搞不清楚權重,而撰寫大量又互相覆蓋的 CSS,造成管理不易且容易出錯,透過這篇教學,相信應該能幫助大家清楚掌握 CSS 選擇器的權重用法!

意見回饋

如果有任何建議或問題,可傳送「意見表單」給我,謝謝~

CSS 教學

基本介紹

認識 CSS 開始使用 CSS CSS 語法規則 CSS 命名原則

CSS 選擇器

認識 CSS 選擇器 優先順序 ( 權重 ) 樣式繼承與聯集 元素選擇器 ID 和 Class 選擇器 屬性選擇器 文件結構選擇器 虛擬類別選擇器 ( 結構 ) 虛擬類別選擇器 ( 類型 ) 虛擬類別選擇器 ( 輸入 ) 虛擬類別選擇器 ( 行為 ) 虛擬類別選擇器 ( 超連結 ) 虛擬類別選擇器 ( 邏輯 ) 虛擬類別選擇器 ( 其他 ) 虛擬元素選擇器 群組與組合選擇器

數值與單位

關鍵字與文字數值 長度與角度單位 顏色單位 位置名稱與時間單位

變數與內容函式

變數 數學計算 文字與清單計數 生成內容與引號

顏色與濾鏡

色彩模型 漸層色 影像濾鏡

文字樣式

使用通用字型 使用外部字型 @font-face 定義字型 文字尺寸 常用文字樣式 文字換行 文字空白與 Tab 大小 文字行高與縮排 文字水平與垂直對齊 文字書寫方向 特殊文字樣式

元素容器

容器顯示類型 ( display ) 元素 display 對照表 盒子模型 ( Box Model ) 寬度與高度 內邊距 ( padding ) 外邊界 ( margin ) 邊框 ( border ) 邊框圓角 影像邊框 輪廓 ( outline ) 可見性與透明度 內容溢出與裁切

背景與陰影

背景顏色 背景圖 ( 定位、尺寸 ) 背景圖 ( 固定、重複 ) 背景圖 ( 多重背景、混合 ) 背景縮寫 ( background ) 容器陰影 ( box-shadow )

清單與表格

清單樣式 清單計數器 定義計數規則 表格基本樣式 表格邊框樣式 表格內容寬度與對齊

基本排版與定位

元素排版方式 浮動 ( float ) 浮動形狀 定位 ( position )

Flexbox 彈性排版

Flexbox 彈性盒子 Flexbox 對齊方式 Flexbox 彈性伸縮

Grid 網格排版

Grid 網格容器與格線 Grid 網格空間與命名 Grid 網格流向與間距 Grid 排列網格項目 Grid 項目對齊與順序

轉場與動畫

轉場 ( transition ) 轉場觸發事件 動畫 ( animation ) 動畫觸發事件 多重動畫的權重與順序

變形、裁切與遮罩

裁切路徑 ( clip-path ) 影像遮罩 ( mask )