前端基礎

-

為甚麼你寫的 CSS 沒有效果 - CSS 選擇器的優先級、權重

this.web

為甚麼你寫的 CSS 沒有效生效呢?

在 CSS 中優先級可以分成 0 ~ 5 共 6 個等級,數字越大,優先級越大,比如說 !important 就是 5 級優先級,所以他可以覆蓋所有的選擇器。

0 級:通配選擇器、選擇符、邏輯偽類

  • 通配選擇器寫作星號 * 功用是一次選取全部的元
  • 選擇符是指+ > ~ 空格等等
  • 邏輯偽類是指 :not( ) :is( )等等

0 級優先級代表它不影響優先級順序

1 級:元素選擇器,例如

p {
  color: red;
}

2 級:類選擇器、屬性選擇器、偽類,如下

.btn {
  color: blue;
}
[href] {
  color: red;
}
:hover {
   color: blud;
}

3 級:ID 選擇器

#myBtn {
  color: green;
}

4 級:inline style,就是在 HTML 標籤直接寫 style

<button style="color: blue">click</button>

5 級:!important

基本上不建議使用,因為它會造成維護的困擾

.btn {
  color: blue !important;
}

CSS 優先級的例子

我來舉個例子讓你更了解優先級的概念

<p class="class-p" id="id-p">text</p>

<style>
#id-p {
  color: red;
}

.class-p {
  color: blue;
}

p {
  color: green;
}
</style>

你覺得字是什麼顏色的呢?

答案是紅色的喔,因為 id 的優先級比較高,所以會蓋過 class 和 p 選擇器。

CSS 組合優先級的計算

那如果是由一段選擇器組合的 CSS,要怎麼判斷優先級呢?例如:

ul > li.my-list {
  color: red;
}

我們可以給每個優先級一個分數來計算

  1. 0 級 : 0 分
  2. 1 級 : 1 分
  3. 2 級 : 10 分
  4. 3 級 : 100 分

每出現一個優先級就加相對的分數,至於 4、5 級就不用計算了,恩為他們是絕對優先的。

所有我們可以知道 ul > li.my-list 是 12 分。因為他出現兩個標籤選擇器和一個類選擇器。

接下來讓我考考你。

CSS 組合優先級的例子

<div class="container">
  <p class="container-p">text</p>
</div>

<style>
.container-p {
  color: red;
}

.container {
  color: blue;
}

.container .container-p {
  color: green;
}

.container > p {
  color: orange;
}
</style>

這個字是什麼顏色的呢?

答案是綠色喔!因為它的優先級分數是 20 分。

/* 10 分 */
.container-p {
  color: red;
}

/* 10 分 */
.container {
  color: blue;
}

/* 20 分 */
.container .container-p {
  color: green;
}

/* 11 分 */
.container > p {
  color: orange;
}

組合計算要注意的地方

不過要注意的是,這個分數算法並不是非常嚴謹的,它不能代表說我用十個 class 選擇器就能蓋過 id 選擇器,基本上優先級的鴻溝是無法跨越的。

你就算用 100 個 class 選擇器也比不過一個 id 或 !important。

但沒有人會在開發時連續寫十個以上的 class 選擇器,所以在 99.9% 的情況下都可以使用這套分數系統。

而如果優先級分數相同的情況下,就會採後來居上原則,也就是寫在後面的優先級高於前面的。

p {
  color: blud;
}

/* 其他 css */

p {
  color: red;
}

這樣情況下,文字顏色會是紅色的。

優先級跟 DOM 位置無關

<div class="blue">
  <div class="red">
    <p>text<p>
  </div>
</div>

<div class="red">
  <div class="blue">
    <p>text<p>
  </div>
</div>

<style>
.blue > p {
  color: blue;
}

.red > P {
  color: red;
}
</style>

你覺得字是什麼顏色的呢?一紅一籃嗎?

答案都是紅色的喔!他們兩個優先級相同,但紅色寫在下面優先級比較高,跟 DOM 位置一點關係都沒有。

小結

到這邊你應該也就知道位什麼有時候你寫的 CSS 不生了,是因為優先級太低了。

但這種時候不建議直接加 !important ,這會讓後續維護便困難。(這樣老闆就找不到人可以取代你了?)

如果是個人小專案,可以重新審視一下自己的 HTML 架構和 CSS 命名,看看到底哪裡出問題。

.myClass.myClass {
  color: red
}

重複寫兩次相同的類名,就可以提高優先級,當然這是不好做法中比較好的做法了。

相關系列文章