iT邦幫忙

1

[快速入門前端 18] CSS 選擇器的權重

  • 分享至 

  • xImage
  •  

選擇器的優先順序

當我們使用多個選擇器選中同個元素,並賦予某個屬性不同值時,就會產生樣式衝突。舉例來說,當我們在 A 選擇器將元素的顏色設為紅色,又用 B 選擇器將同個元素的顏色設為綠色,那該元素的文字到底會是什麼顏色呢?
其實選擇器的優先級又分很多個層面,若以 CSS 撰寫位置來看的話:行內樣式 > 內部嵌入 > 外部引入,而在同個位置同種選擇器衝突時,後面的樣式會將前面的樣式覆蓋過去

範例:(CSS 衝突)
下面兩段選擇器都對 p 元素作用,且 color 屬性值衝突,後面的樣式會將前面的樣式設定覆蓋。

p {
    color: red; /* 有衝突,被後面覆蓋,p 內文字最終呈現黃色 */
    font-size: 30; /* 無衝突,不影響 */
}
p {
    color: yellow; /* 有衝突,覆蓋掉前面的設定 */
}

但在選擇器的寫法不同時,優先度又會是如何呢?
簡單來說,選擇器的優先級大概是

行內樣式 > ID 選擇器 > Class 類別選擇器 > 元素選擇器 > 通配符選擇器

在 CSS 規則中,選擇器優先度較高的不會被優先度低的覆蓋。

範例:
在下面程式中,#myd.color 都指向同一個元素 p,而 #myId 寫在前面、.color 寫在後面,但因為 ID 選擇器優先度較高不會被優先度低的選擇器覆蓋,所以文字最終呈現紅色。

#myId {
    color: red;
}
.color {
    color: yellow;
}
<p id="myId" class="color">我是紅色的</p>

其實在 CSS 樣式中還有一個 BUG,他可以打敗所有選擇器和寫法,只要有他在就一定是優先度最高的,那就是 !important。故名思義 !important 的意思就是將某個選擇器中的某個屬性值設為最高權重,而他的用法為 屬性名: 屬性值 !important;,直接以空格連接加在屬性值後面。
注意,這邊 important 增加的是單個屬性的權重,而不是整個選擇器的權重,指對該屬性有用。

範例:(!important)
!important 會將該屬性設為最高級,不論先後順序和選擇器優先度為何都不會被覆蓋。

p {
    color: red !important; /* 有衝突,但我有 importan,不會被覆蓋 */
    font-size: 30; /* 有衝突,被覆蓋 */
    background-color: blud; /* 無衝突,不影響 */
}
p {
    color: yellow; /* 有衝突,但他有 importan,所以我輸了*/
    font-size: 40; /* 有衝突,覆蓋掉前面的 */
}

總結

CSS 樣式優先度為

!important > 行內樣式 > ID 選擇器 > Class 類別選擇器 > 元素選擇器 > 通配符選擇器 > 若選擇器相同則後面覆蓋前面

如何計算權重

前面講了這麼多需要死記硬背的規則,可能會有人好奇權重到底是如何計算的呢?其實很簡單,只要將選擇器分類為三種並進行比較就好啦。

權重計算

在權重計算中,我們會將選擇器分為三種類型,並計算出它們的個數成為 (a, b ,c) 的形式。

a:ID 選擇器 的個數
b:Class 選擇器、偽類選擇器、屬性選擇器 的個數
c:元素選擇器、偽元素選擇器 的個數

讓我們來舉幾個例子

  • 只有一個 ID 選擇器,依規則分類為 a ,個數 1,權重為 (1, 0, 0)
    https://ithelp.ithome.com.tw/upload/images/20230523/20158509loBv2Ay80V.jpg
  • 只有一個 ID 選擇器,依規則分類為 b ,個數 1,權重為 (0, 1, 0)
    https://ithelp.ithome.com.tw/upload/images/20230523/20158509KUcEWmQ3z1.jpg

那複雜的複合選擇器該如何計算呢?其實概念是一樣的

  • 一個 Class 和一個偽類,分類皆為 b,權重為 (0, 2, 0)
    https://ithelp.ithome.com.tw/upload/images/20230523/20158509JSpeOhyn9J.jpg
  • ID 選擇器為 a 類、元素選擇器為 c 類、Class 選擇器為 b 類,權重為 (1, 1, 1)
    https://ithelp.ithome.com.tw/upload/images/20230523/20158509EFUijrpbiE.jpg
  • Class 選擇器為 b,元素及偽元素皆為 c,權重為 (0, 1, 3)
    https://ithelp.ithome.com.tw/upload/images/20230523/201585093oLT9sH3P1.jpg

Tips: 在 VSCode 中,只要將滑鼠移到選擇器上方,就會看到算好的權重囉
https://ithelp.ithome.com.tw/upload/images/20230523/20158509ZystfBh357.png

權重比較

權重的比較順序為 a -> b -> c,若前一位數相等才需要繼續往下比,否則就依照大小決定權重順序。也就是說不管後面兩項如何, (1, n, m) 永遠大於 (0, x, y),而這個算法也符合了我們最前面所說的 ID 選擇器 > Class 類別選擇器 > 元素選擇器

舉例:
#myID (1, 0, 0) > .myClass (0, 1, 0)
#myID:hover (1, 1, 0) > .myClass::after (0, 1, 1)

重點

  • 通配符 (*) 的權重為 0
  • 含有 !important 的樣式為最優先
  • 行內樣式高於所有權重,但低於 !important
  • 先比權重(選擇器優先度),權重相同時前面的樣式會被後面的覆蓋

上一篇:[快速入門前端 17] CSS 選擇器 (7) 選擇器總結
下一篇:[快速入門前端 19] CSS 三大特性:層疊性、繼承性、優先級
系列文章列表:[快速入門前端] 系列文章索引列表


圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言