Skip to content

CSS Specificity 優先權

當多個 CSS 規則選取到同一個元素並設定相同的屬性時,瀏覽器需要決定哪個規則的值會被實際應用,這個決定過程就是基於 CSS 優先權。

影響優先權的因素有那些? 如下:

  • 樣式撰寫的位置。
  • 選取器類型。

影響優先權的因素

樣式撰寫的位置

一般來說,瀏覽器渲染網頁的順序為: 由上而下、由左至右。因此,下方原始碼的優先權為:

行內樣式 > 文件樣式 > 外部樣式

html
<!DOCTYPE html>  
<html lang="zh-Hant-TW">  
  <head>  
    <meta charset="UTF-8">  
    <title>Document</title>  
    <link rel="stylesheet" href="./style/all.css">  
    <style>  
      h1 {  
        color: red;  
      }  
    </style>  
  </head>  
  <body>  
    <h1 style="color: blue;">優先權測試</h1>  
  </body>  
</html>
css
h1 {  
  color: yellowgreen;  
}

若樣式的原始碼順序有所改變,亦會影響優先權。因此,下方原始碼的優先權為:

行內樣式 > 外部樣式 > 文件樣式

html
<!DOCTYPE html>  
<html lang="zh-Hant-TW">  
  <head>  
    <meta charset="UTF-8">  
    <title>Document</title>  
    <style>  
      h1 {  
        color: red;  
      }  
    </style>  
    <link rel="stylesheet" href="./style/all.css">  
  </head>  
  <body>  
    <h1 style="color: blue;">優先權測試</h1>  
  </body>  
</html>
css
h1 {  
  color: yellowgreen;  
}

警告

不要把樣式分三處來撰寫且控制同一個對象的屬性,以免造成混亂。

選取器類型

選取器類型的不同亦會造成優先權的狀況發生。下方原始碼的優先權為:

inline style > id > class > element

html
<ul>  
  <li id="Item" class="item" style="color: green;">優先權測試</li>  
  <li>優先權測試</li>  
  <li>優先權測試</li>  
  <li>優先權測試</li>  
  <li>優先權測試</li>  
</ul>
css
#Item {  
  color: blue;  
}  
  
.item {  
  color: red;  
}  
  
li {  
  color: pink;  
}

警告

不要用各種不同類型的選取器控制同一個對象的屬性,以免造成混亂。

優先權計算方式

CSS 優先權使用五位數的計分系統來計算,從左到右分別代表:

  1. !important 聲明。
  2. 行內樣式。
  3. ID 選取器。
  4. 類別、屬性、偽類選取器。
  5. 元素選取器。

計分規則

選取器類型分數範例
!important1, 0, 0, 0, 0color: blue !important;
行內樣式0, 1, 0, 0, 0style="color: red;"
ID 選取器0, 0, 1, 0, 0#header
類別選取器0, 0, 0, 1, 0.nav
偽類選取器0, 0, 0, 1, 0:hover
屬性選取器0, 0 ,0, 1, 0[type="text"]
元素選取器0, 0, 0, 0, 1div
偽元素選取器0, 0, 0, 0, 1::before
通用選取器0, 0, 0, 0, 0*
  1. 基本計算

    在以下例子中,p.text 的優先權最高 (0, 0, 0, 1, 1),所以文字色彩會是 green。

    css
    /* 0, 0, 0, 0, 1 */
    p { color: blue; }
    
    /* 0, 0, 0, 1, 1 */
    p.text { color: green; }
    
    /* 0, 0, 0, 1, 0 */
    .text { color: red; }
  2. 複雜計算

    在以下例子中,#content p.special 的優先權最高 (0, 0, 1, 1, 1),所以文字色彩會是 purple。

    css
    /* 0, 0, 0, 0, 2 */
    div p { color: blue; }
    
    /* 0, 0, 0, 1, 1 */
    div .highlight { color: red; }
    
    /* 0, 0, 1, 1, 1 */
    #content p.special { color: purple; }
    
    /* 0, 0, 1, 0, 1 */
    #content p { color: green; }

特殊情況

!important 聲明

!important 聲明具有最高的優先權,會覆蓋其他所有規則。若有兩個選取器都用了 !important,則會再比較它們之間的優先權。

css
p { color: blue !important; }
#content p { color: red; } /* 即使 ID 選取器優先權較高,仍會被覆蓋 */

實用技巧

避免過度使用 !important

css
/* ❌ 不推薦 */
.button { 
  background: red !important; 
}

/* ✅ 推薦 */
.button.primary { 
  background: red; 
}

使用合適的選取器優先權

css
/* ❌ 優先權過高,難以覆蓋 */
#header #nav ul li a { color: blue; }

/* ✅ 適當的優先權 */
.nav-link { color: blue; }

善用 CSS 的順序

利用 CSS 的層疊特性,讓樣式表的順序協助管理優先權:

css
/* 基礎樣式 */
.button { 
  background-color: gray; 
  color: white; 
}

/* 變體樣式,放在後面 */
.button.primary { 
  background-color: blue; 
}

常見問題

Q: 為什麼我的樣式沒有生效?

A: 檢查優先權是否足夠高,或者是否被其他規則覆蓋。

Q: 什麼時候可以使用 !important?

A: 僅在需要覆蓋第三方樣式庫或處理遺留代碼時謹慎使用。

總結

最佳實踐方式

  • 保持選取器簡潔: 避免使用過於複雜的後代選取器。
  • 使用類別選取器: 類別選取器提供適中的優先權且易於維護。
  • 避免行內樣式: 行內樣式難以維護且優先權過高。
  • 謹慎使用 ID 選取器: ID 選取器優先權較高,應用於樣式時需特別注意。
  • 利用 CSS 架構: 如 BEM 方法論來管理選取器命名和優先權。