HTML CSS

初學程式設計必學CSS權重整理

王瑀琦 2018/08/30 14:10:59
4789

初學程式設計必學CSS權重整理


簡介

寫網頁程式時是否曾有過套用某CSS設定到指定物件時卻無法產生變化,開始懷疑自己程式打錯甚至開始愈改愈錯的情況,其實只是忽略了最重要的CSS權重優先順序的觀念,深入了解後可以讓未來的程式碼更加簡潔有組織,減少許多對程式的挫敗感。

作者

王瑀琦


寫網頁程式時是否曾有過套用某CSS設定到指定物件時卻無法產生變化,開始懷疑自己程式打錯甚至開始愈改愈錯的情況,其實只是忽略了最重要的CSS權重觀念。

權重觀念其實就是CSS的使用優先權,必須了解:

1.若同時在一個頁面上產生相同的CSS的話,後面的會直接覆蓋掉前面的。
2.若是兩個不同層級的CSS同時設定在相同物件上時,強度愈高的會優先蓋過其他的。

例如:

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

</style>

<body>

    <div><p>123</p></div>

</body>

相同的CSS產生時,下面的會覆蓋掉上面的,因此上面範例,p的文字顏色會是----------藍色。


<style>
    #p{color: red;}
    p{color: blue;}

</style>

<body>

    <div><p id="p">123</p></div>

</body>


若是設定了一個id名稱為p,兩個物件指向如果相同,雖然id的p排在上層,但會因為id的強度較高而使此處文字呈現----------紅色。

 

要如何判定誰的層級較高呢?以下是詳細說明

將CSS權重分成四種等級,分別為A-B-C-D,A為最高階層,D為最低階層,相同階層中數字愈高,強度就愈強。

亦可將層級A-B-C-D想像成分為皇帝-大臣-地方官員-庶民,因1個皇帝說的話100個大臣也無法抵抗,一個大臣說的話上千個庶民也無法反抗,以此類推,可見權重關係對整個CSS影響非常的息息相關,了解了其中的原理,指令下對地方,絕對能使未來寫的程式更簡潔有條理。

基本的CSS的權重計算

* < Element(Type/標籤) < Class < ID < inline style < !important


*

*為全站預設值,所以只要權重超過就可以覆蓋過它的預設。

全站預設值
*{
   background-color: green;
}


此類別權重為0-0-0-0。

 
 
 
Element (type/標籤)
Element 總共有哪些呢?下面列出部分常見的,其他的請參考

MDN https://developer.mozilla.org/zh-TW/docs/Web/HTML/Element

 
Pseudo-elements 偽元素
 ::after、::before、::first-letter、::first-line、::selection
 

以上兩種的權重都是 0-0-0-1。

 

 
 
class
class在 html 上面會寫成 class="className" ,在 css 內長這樣 .className ,前方會有一個點”.”。在同一個檔案的程式裡,可容許多個物件使用一樣的class名稱,統一管理,舉例來說,有點像學校裡同一個班級(class)可以有很多個學生。
 
 
psuedo-class(偽元素)
:nth-child() 、 :link 、 :hover 、 :focus 等

:only-of-type 、 :nth-of-type

更多偽元素請參考:https://www.w3schools.com/css/css_pseudo_elements.asp

 
 
attribute(屬性選擇器)

[type:checkbox]、[attr]

 
以上三種的權重都是 0-0-1-0 。

 
 
 
id
id 在 html 上面是這樣寫的 id="home" ,在 css 內長這樣 #home ,前方會帶井字號。在同一檔案的程式裡,只能使用一個id的名稱,且指定在一個物件上,不能有二個不同的物件使用同一個id名稱,舉例來說,一個班級裡一個人會有一個學號,且整個學校使用這個學號的也只會有這一個學生。
 

每一個 id 的權重都是 0-1-0-0。

 
 
 
inline style attribute
所謂的 inline style attribute 就是寫在 html 行內的 style。
 

inline style attribute 的權重為 1-0-0-0 。

 
 
 
!important
還有一個終極大魔王叫做 !important

!important 的權重非常高,可以蓋過所有的權重

以文中最上的舉例中,若id為皇帝層級,!important 就相當於上天了XD


用法如下:

.product{
   width: 200px!important;
}
 
只有 !important 能超越 !important,所以沒事不要亂用

當你在任何一段 css 裡面下了 !important,如果想要覆蓋原本的 css ,後來寫的 css 必須也加上 !important 才行。像這種暴力式壓制法,會破壞所有以上所說的階層機制,庶民也可以勝過皇帝,因為有了老天的幫忙,這將會造成CSS秩序上的錯亂,所以當了解了CSS的層級規範後,會發現不到最後關頭,盡量不會使用此方式。

 

例如:

[ 圖1 ]  程式CSS順序雖然id在上面class在下面,但我們都知道id權重為0-1-0-0遠比

class的0-0-1-0還要來得大,這種情況id不管放在任何位置都是能覆蓋掉class的,所以結果當然會是??------------藍色方框。

[ 圖2 ]  同樣的程式裡加上了!important,會怎樣呢?結果是,程式將會暴力式的將c1直接進階成最強大的等級,使其功能最強化,所以此程式結果會是??-------------紅色方框。

 
圖1
圖2
 

那麼來試試看計算權重的方式:

ul>li 都是 element 所以加起來是 0-0-0-2
body div ul li a span 總共 6 個 element 所以加起來是 0-0-0-6
.myclass li 一個 element 加上一個 class ,所以是 0-0-1-1
.myclass li a 兩個 element 加上一個 class ,所以是 0-0-1-2
form input[type=email] 兩個 element 、一個 attribute,所以是 0-0-1-2

經過以上的介紹,簡單的做個小小遊戲,大家來試試看程式的最後,1-7號各會是什麼顏色的字,答案將會提供在最底部,預祝大家能全部答對喔。

 

權重問題除了基本的這些之外,必須知道的是,CSS擺放的位置有哪些呢?
1. 將CSS直接寫在HTML的body裡成為上述僅次於!important的inline style。
例:
 
2. 將CSS寫在HTML的<head></head>之間。
例:
 
3. 將CSS寫在外部的CSS檔,在HTML檔內新增連結位址,連接該CSS檔。
例:已做好一個CSS檔案名稱叫做myStyle放置在CSS資料夾中的話,在HTML裡<head></head>之間寫下連結位置,即可使其檔案CSS在此HTML檔案中發生作用。
 
上述每個位置擺放的CSS也有權重的差別,需要特別注意。

沒有設定important的情況下,若CSS名稱相同,分別放置在上述不同的地方,也會有權重高低的差別。

 

以下做個小實驗:

在HTML的地方,在四個地方針對<p>標籤放置了CSS設定文字的顏色,其中包括了上述的三種地方之外,還有使用link時若同時有兩個link時的狀況也一並考慮,做了以下的程式。

 

(HTML的樣子)
(link裡myStyle_one檔案裡的樣子)
 
(link裡myStyle_two檔案裡的樣子)
 
 

這樣的程式裡第一個跑出來的文字會是什麼顏色呢??

順序又是如何呢??

 

 

答案是-------------藍色(將CSS直接放在HTML的body裡--inline style)

 

 

 

拿掉此串設定後,會是-----------紅色(將CSS寫在HTML的<head></head>之間)

 

 
 
再拿掉此串設定後,會是----------綠色(CSS寫在外部連結的CSS檔在連結進HTML裡,link放在較下面)
 
 
 
再拿掉此串設定後,會是----------黃色(CSS寫在外部連結的CSS檔在連結進HTML裡,link放在較上面)
 

以上的實驗證明,放置CSS的時候

inline style > <head></head>之間 > 外部連結link放置在下面 >  外部連結link放置在上面


因此為了工作上的修改和維護方便,建議盡量避免使用較高權重的方式,以免未來要增設設定時,東西很難搬移或更動設定,不重要的CSS可以使用外部連結放置在link上面位置的方式,因為就算程式被覆蓋過去也是沒有關係的,例如bootstrap的內建CSS就很適合擺在link的最上面位置。

 

問題來了,如果我在中間有設定!important的話呢?

是否又會崩壞原本應有的權重規則呢?


我將上述權重最弱的黃色上面設定了!important,再次測試看看,會發生什麼事呢??

 

(link裡myStyle_one檔案裡的樣子)

 
 
答案是,他依然是超級大魔王,會破壞所有層級關係,就算是最弱的情況下,也會瞬間變成最強等級,又再次證明只有!important可以蓋過!important。
 

 

由以上這些實驗中,得到的結論是,一開始設定網頁時,最好從權重小的地方開始下手,免得一開始下手太重後面要改東西時,欲哭無淚。能用class就盡量使用class,因為一個物件可以放置多個class,一個蓋不過可以放兩個、三個、四個,遇到特殊情況需要特別設定時,再使用id助陣,!important除非萬不得已,千萬別輕易使用,尤其是inline style上放置!important,他可以說是世紀大魔王等級。


希望瞭解了權重關係後,大家都能清楚自己東西改不動時,是因為哪邊可能出現問題,能快速找到自己的問題點,讓網頁能愈寫愈順暢。


小遊戲的答案區:
 

 

重點小整理:

   1. 強度相同時,後方的CSS會蓋掉前方的設定值

   2. class 的順序是以style標籤中的為主

   3. 權重優先順序是id > class > Element(Type/標籤) > *

   4. CSS中若名稱沒有完全對應到HTML的名稱的話不會產生錯誤,但也不會影響到任何網頁的外觀的。

王瑀琦