重點整理
- 有重複的 CSS 樣式規則套用到同一個 HTML 元素上的時候,權重(specificity)高的樣式會覆蓋權重低的樣式設定。
- 原始碼中位置越下方(後發)的 CSS 樣式會複寫先寫出來的樣式。
- 樣式規則有衝突的時候,權重較高的樣式會覆蓋權重低的樣式。衝突規則的權重一樣大的時候,後發的樣式會覆蓋先寫的樣式。
Specificity
Specificity(以降以「權重」稱之)的高低影響哪一些 CSS 樣式會發生作用。 設定好的 CSS 沒有作用,可能就是 CSS 樣式的權重沒有妥善安排,導致編寫好的 CSS 樣式沒有如預期般套用到 HTML 元素上。
權重從低至高順位分組如下:
-
universal selector 與 inherited style:使用
*選取「全部」與繼承得來的樣式,兩者的權重皆為0-0-0-0-0;最低的權重 -
element selector、::pseudo-element selector:選取 HTML 元素或偽元素,權重為
0-0-0-0-1- HTML 元素:html、body、section、div、p……等 HTML 元素(element)
- 偽元素:
A CSS pseudo-element is a keyword added to a selector that lets you style a specific part of the selected element(s).
參考MDN,偽元素指的是 HTML 元素的「某一個部份」,較常見的大概是
::after、::before與::first-letter -
.class selector、:pseudo-class selector、[attribute] selector:選取 class、偽類或具有特定屬性(attribute)的 HTML 元素,權重為
0-0-0-1-0- 偽類:
A CSS pseudo-class is a keyword added to a selector that specifies a special state of the selected element(s).
參考MDN,偽類指的是 HTML 元素的「某一種狀態」,最常見的大概是
:hover- 屬性:參考MDN,以
input[type="checkbox"]為例,就是「選取所有是 checkbox 特性的 input 元素」
- 偽類:
-
#id selector:選取擁有某 id 的 HTML 元素,權重是
0-0-1-0-0 -
inline style(比如
<p style="color: red;">text</p>):權重是0-1-0-0-0,不過這樣會讓原始碼的維護性變差,所以還是避免使用吧 -
!important:擁有最大的權重1-0-0-0-0,而後發的!important會壓過先寫出來的!important
權重的計算方式
參考以上劃分的六種權重分組,將選取器中屬於同一組的選擇器條件相加後進行比大小。
舉個 🌰,假設以下兩種color的樣式設定位在同一份原始碼裡面:
#blue { /* 第一組樣式 */ color: blue;}
div p { /* 第二組樣式 */ color: red;}而 HTML 內容如下:
<div> <p id="blue"> Lorem ipsum dolor, sit amet consectetur adipisicing elit. Consectetur, magnam! </p></div>第一組樣式的選取器為#id 一個,權重為:0-0-1-0-0
第二組樣式的選取器為 HTML 元素兩個,權重為:0-0-0-0-2
第一組樣式的權重大於第二組,故以上的<p>會是藍色:
See the Pen css specificity by Charlie (@Charlie7779) on CodePen.
需注意的是,CSS 的權重並不是十進位制,選取五十個.class 做出來的 CSS 樣式也比不過選取一個#id 宣告出來的樣式。
舉個 🌰,假設以下兩種background-color的樣式設定位在同一份原始碼裡面:
#yellow { background-color: yellow;}
.c1 .c2 .c3 .c4 .c5 .c6 .c7 .c8 .c9 .c10 .c11 { background-color: green;}而 HTML 內容如下:
<div class="c1"> <div class="c2"> <div class="c3"> <div class="c4"> <div class="c5"> <div class="c6"> <div class="c7"> <div class="c8"> <div class="c9"> <div class="c10"> <div class="c11" id="yellow"></div> </div> </div> </div> </div> </div> </div> </div> </div> </div></div>那麼該<div>的背景顏色會是黃色:
See the Pen css specificity by Charlie (@Charlie7779) on CodePen.
在 CSS Specificity 的宇宙裡,團結起來的五十個.筷子還是會被#●門夾爆的。
快速判別樣式的權重
!important最大,有複數個!important就看哪一段樣式最後被執行- element 贏不過.class 與[attribute],.class 與[attribute]贏不過#id
- 使用人家寫好的計算機:Specificity Calculator

權重相等時,後發覆蓋先寫的樣式
假設style.css的內容如下:
p { color: blue;}而 HTML 內容如下:
<!DOCTYPE html><html lang="en"> <head> <link rel="stylesheet" href="./style.css" /> <style> p { color: green; } </style> </head>
<body> <p> Lorem ipsum dolor, sit amet consectetur adipisicing elit. Consectetur, magnam! </p> </body></html>因為<style>比<link rel="stylesheet" href="./style.css">晚執行,所以<p>會是綠色(按下▶執行程式碼看結果):
而如果調換<style>與<link rel="stylesheet" href="./style.css">的順序:
<!DOCTYPE html><html lang="en"> <head> <style> p { color: green; } </style> <link rel="stylesheet" href="./style.css" /> </head>
<body> <p> Lorem ipsum dolor, sit amet consectetur adipisicing elit. Consectetur, magnam! </p> </body></html><p>就會是藍色(按下▶執行程式碼看結果):
LVHA
問:為什麼超連結的 CSS 樣式最好以「link-visited-hover-active」的順序從上到下書寫? 答:因為樣式權重相等的時候,後發的樣式會覆蓋先寫的內容。 假設使用「link-hover-active-visited」的順序來設定 CSS 樣式:
a:link { color: blue;}a:hover { color: aqua;}a:active { color: red;}a:visited { color: purple;}那一個被點擊過的(:visited)超連結,即使在:hover或:active的狀態,也不會被套上:hover或:active的樣式,因為:hover與:active通通被:visited的樣式蓋過去了。
點擊過以下範例的超連結後,即使把游標停留在連結上,文字也不會變為水藍色:
See the Pen LHAV by Charlie (@Charlie7779) on CodePen.
但如果把樣式順序修改如下:
a:link { color: blue;}a:visited { color: purple;}a:hover { color: aqua;}a:active { color: red;}這個超連結就可以表現出四種不同狀態的樣式。
先點擊以下範例的超連結,超連結的文字會變成紫色,但因為:hover與:active的樣式順序在:visited以下,所以當游標停留在連結上(狀態為:hover)時,文字會變成水藍色;而點下超連結(狀態為:active)時,文字會變成紅色:
See the Pen LVHA by Charlie (@Charlie7779) on CodePen.
規則衝突時,後發覆蓋先寫的樣式
舉個 🌰,假設以下兩種針對<p>的樣式設定位在同一份原始碼裡面:
p { color: red; background: blue;}
p { color: yellow;}衝突的規則只有color,background不受影響,所以最後<p>的樣式會是「藍色背景、黃色文字」:
See the Pen css specificity by Charlie (@Charlie7779) on CodePen.
透過繼承得到的樣式,權重是 0-0-0-0-0
舉個 🌰,假設以下兩種樣式設定位在同一份原始碼裡面:
#parent { color: green;}
h1 { color: red;}而 HTML 內容如下:
<html> <body id="parent"> <h1>A Title</h1> </body></html><h1>從<body id="parent">繼承到的文字色彩樣式會被 CSS 樣式表中的h1覆蓋掉(樣式h1的權重是 0-0-0-0-1),<h1>A Title</h1>會是紅色:
See the Pen inherited styles by Charlie (@Charlie7779) on CodePen.