前端基礎
-為甚麼你寫的 CSS 沒有效果 - CSS 選擇器的優先級、權重
為甚麼你寫的 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;
}
我們可以給每個優先級一個分數來計算
- 0 級 : 0 分
- 1 級 : 1 分
- 2 級 : 10 分
- 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
}
重複寫兩次相同的類名,就可以提高優先級,當然這是不好做法中比較好的做法了。