CSS 優先級 (Specificity)

當多條 CSS 規則都套用到同一個元素時,瀏覽器會根據「優先級」來決定最終套用哪一條規則。優先級的計算方式稱為「權重」(specificity)。

優先級順序

從高到低的優先級順序:

  1. !important(最高優先級)
  2. 行內樣式 (inline style)
  3. ID 選擇器
  4. Class 選擇器、屬性選擇器、偽類
  5. 元素選擇器、偽元素
  6. 通用選擇器 *(最低優先級)

權重計算

CSS 權重可以用一個四位數來表示:(a, b, c, d)

  • a:行內樣式,有則為 1,沒有則為 0
  • b:ID 選擇器的數量
  • c:Class 選擇器、屬性選擇器、偽類的數量
  • d:元素選擇器、偽元素的數量

比較時從左到右,數字大的優先級高。

範例計算

/* (0, 0, 0, 1) - 一個元素選擇器 */
p { color: black; }

/* (0, 0, 1, 0) - 一個 class */
.text { color: blue; }

/* (0, 1, 0, 0) - 一個 ID */
#content { color: green; }

/* (0, 0, 1, 1) - 一個元素 + 一個 class */
p.text { color: red; }

/* (0, 1, 1, 1) - 一個 ID + 一個 class + 一個元素 */
#content p.text { color: purple; }

/* (0, 0, 2, 0) - 兩個 class */
.container .text { color: orange; }

/* (0, 0, 1, 2) - 一個 class + 兩個元素 */
div p.text { color: pink; }

實際比較

<p id="intro" class="highlight">這段文字是什麼顏色?</p>
p { color: black; }                 /* (0,0,0,1) */
.highlight { color: yellow; }       /* (0,0,1,0) */
p.highlight { color: orange; }      /* (0,0,1,1) */
#intro { color: blue; }             /* (0,1,0,0) - 勝出! */

結果:文字會是藍色,因為 ID 選擇器的權重最高。

!important

!important 可以強制提升某個樣式的優先級到最高。

p {
  color: red !important;
}

#intro {
  color: blue;  /* 即使是 ID 選擇器,也會被上面的 !important 覆蓋 */
}
盡量避免使用 !important,因為它會破壞 CSS 的正常優先級規則,讓程式碼變得難以維護。如果發現需要大量使用 !important,通常表示 CSS 架構需要重新設計。

什麼時候可以用 !important

  • 覆蓋第三方套件的樣式
  • 工具類別 (utility classes),例如 .hidden { display: none !important; }
  • 確實需要確保某個樣式不會被覆蓋的情況

相同權重時的規則

當兩條規則的權重完全相同時,後面寫的規則會覆蓋前面的。

.text {
  color: blue;
}

.text {
  color: red;  /* 後面的會生效,文字是紅色 */
}

繼承 (Inheritance)

有些 CSS 屬性會自動從父元素繼承到子元素,例如:

  • color
  • font-family
  • font-size
  • line-height
  • text-align
body {
  color: #333;
  font-family: Arial, sans-serif;
}

/* 所有在 body 內的元素都會繼承這些樣式 */

但有些屬性不會繼承,例如:

  • margin
  • padding
  • border
  • background
  • widthheight

強制繼承

使用 inherit 值可以強制繼承父元素的屬性值。

.child {
  border: inherit;  /* 繼承父元素的 border */
}

重置樣式

initial

將屬性重置為 CSS 規範中的初始值。

p {
  color: initial;  /* 重置為黑色(瀏覽器預設) */
}

unset

如果屬性可以繼承,則繼承父元素的值;否則重置為初始值。

p {
  color: unset;
}

優先級技巧

提高選擇器權重

如果需要提高優先級但不想用 !important,可以增加選擇器的具體程度:

/* 原本的權重 (0,0,1,0) */
.button { background: blue; }

/* 提高權重 (0,0,2,0) */
.container .button { background: red; }

/* 或重複 class (0,0,2,0) */
.button.button { background: green; }

保持選擇器簡單

盡量使用簡單的選擇器,避免過度具體:

/* 不推薦:太具體 */
body div#container ul.nav li a.link { color: blue; }

/* 推薦:簡潔明瞭 */
.nav-link { color: blue; }