iT邦幫忙

第 11 屆 iT 邦幫忙鐵人賽

DAY 6
4

倘若不斷向深處扎根,就能茁壯成長 - RM

/images/emoticon/emoticon07.gif

前言

在上兩個章節之中,我們提到了選擇器語法、偽類等,學習到選擇器代表的意義,在這一篇文章中,我們會提到 Cascading,那麼究竟什麼是 Cascading 呢?讓我們一起看下去吧~

Casecading

開頭慣例附上直通車:Assigning property values, Cascading, and Inheritance

CSS 全名為 Cascading Style Sheets,中文又可稱為級聯樣式表、階層樣式表等,而特色是同一份 document 可以被引入多個 CSS,除此之外對於同個元素 CSS 同個屬性可以添加不只一次,這使得 CSS 可以非常靈活地被應用。在第一篇文章也有提到,當初樣式表語言百家競爭時這是 CSS 很大的特色。不過,引入多種來源、添加不只一個屬性值雖然方便,但同時也帶來了問題,當同一個元素同時設置多項 CSS 屬性值時,到底要應用哪一個 CSS 屬性值呢?這時候就要說到 Casecading 了,Casecading 本身是 CSS 的特色,它允許多個樣式表影響 document 的展示,當有不同聲明針對同一元素時,會以 Cascade order 的規則解決衝突。

/images/emoticon/emoticon13.gif

一個簡單的問題,這個 <span class="font">HELLO</span> 會是什麼顏色?

span {
	color: pink;
}
.font {
	color: blue;
}

答案當然是藍色,但是為什麼呢?Casecade order 扮演了什麼角色呢?


分配屬性值

Once a user agent has parsed a document and constructed a document tree , it must assign, for every element in the tree, a value to every property that applies to the target media type .

首先,我們拉回來~說到屬性值,當 UA 解析了 document 建立文檔樹後,UA 需要為文檔樹中的每個元素的每個屬性應用一個符合 media type 的屬性值,也就是無論如何,每個元素的每個屬性都會有一個值,而這個值計算會經過Specified values、Computed values、Used values、Actual values。

屬性值計算順序:

  1. Specified values
  2. Computed values
  3. Used values
  4. Actual values

而我們所在意的計算屬性值套用規則,是發生在計算 Specified values 這個步驟,這個步驟中 UA 會根據以下規則順序為每個屬性分配一個屬性值

  1. 樣式表中該元素有設定該屬性值則以這個屬性值為 Specified value
  2. 如果該元素沒有設定該屬性值,而該屬性是屬於 inherit 特性的,則應用該元素父級該屬性的 value,並且該元素需不是根元素。
  3. 假如該元素仍沒有屬性值或屬性值是非 inherit 特性的,則應用該屬性的初始值,每一個元素的初始值在該屬性的定義中指明。

簡單來說,當有設定屬性值就用設定值,沒設定但是該屬性有繼承特性就用父元素的值,再沒有就用初始值,這個機制讓元素中每個屬性都會有屬性值,所以在一般的狀態下,若是我們沒有設定某個元素的某個屬性值,而 UA 樣式表中也沒有設定的話,UA 就會按照 2、3 步驟去給予一個屬性值。

繼承 Inheritance

Some values are inherited by the children of an element in the document tree , as described above . Each property defines whether it is inherited or not.

每個屬性定義中都會聲明這個屬性是否有預設繼承,當沒有設定的屬性值且該屬性具有繼承特性,該繼承就會發生作用。

在規範中給出的繼承值如下,可以看見浮動沒有繼承特性,而初始值為 none

https://ithelp.ithome.com.tw/upload/images/20190921/20111825W6eKY3zqqA.png

當沒有繼承特性但想設定繼承時該怎麼辦?

有的時候我們可能會想讓一個 div 中的 p 邊框繼承(舉例來說,我知道你不會~),但是我們知道邊框沒有繼承特性,這時候就可以在屬性值中設定 inherit ,它便會繼承父元素的屬性值。

Codepen 範例

Casecade

Style sheets may have three different origins: author, user, and user agent.
The CSS cascadeassigns a weight to each style rule. When several rules apply, the one with the greatest weight takes precedence.

在規範中提到了樣式表可能來自三個地方:

  • Author Origin :網頁的開發者。
  • User Origin :網頁使用者。
  • User agent Origin :一般所認知的網頁瀏覽器。

目前新版規範新增兩種來源:Animation Origin、Transition Origin

Casecade order

To find the value for an element/property combination, user agents must apply the following sorting order

回到最初的問題,當有多組屬性值需要套用一組屬性值時,CSS 會有什麼規則呢?這時候就要說到 Casecade order,其實 UA 在樣式有多組屬性值時,會按照下列順序去計算屬性值權重,當比較權重相同時,就在往下一階段比較,進而決定要套用的屬性值。

  1. 找到應用於元素上所有屬性值的 media type,並且比對 media type 是否正確
  2. 比較 casecade 來源(1 為最大)
    1. Transition declarations
    2. Important user agent declarations
    3. Important user declarations
    4. Important author declarations
    5. Animation declarations
    6. Normal author declarations
    7. Normal user declarations
    8. Normal user agent declarations
  3. 比較選擇器 specificity
  4. 最後,若是上述比較都相同,後者屬性值優先

!important

CSS attempts to create a balance of power between author and user style sheets. By default, rules in an author’s style sheet override those in a user’s style sheet (see cascade rule 3).

!important 本身的存在規範寫到是試圖在調適 Author 和 User 之間的平衡,在一般的情況下我們可以看到樣式表來源權重 Author 大於 User ,但是加上 !important 後順序相反,User 權重大於 Author ,這是試圖保有 User 的最大控制權以提高 document 的訪問性(例如部分用戶需要調整字體大小)。

specificity

當多個選擇器同時選中一個元素時,選擇器的 specificity 會有如下的計算方式去比較相互的優先性,也就是大家常在網路上看到的四個零那張圖 ~,這邊網路上有很多資源我便不再贅述,重點是要記得有些來源會說 !important 是第五個零,那個概念與規範說到的不同,規範把 !important 放在樣式表來源的比較中,而非選擇器的比較中。

  • !important 不在此計算中,所以把它當作第五個零的概念是錯誤的呦~

在很以前有聽說過一個傳說,只要集滿 100 個類選擇器,就可以召喚神龍多進位一個零,變個和 ID 選擇器一樣大,不過並不會Codepen 範例

CSS 規範列出的 specificity 示例:
https://ithelp.ithome.com.tw/upload/images/20190921/20111825mg81oJJhrI.png

結語

今天,我們提到了 Casecading 的意義,學習到了多組屬性值下 CSS 如何套用屬性值的規則,雖然比較常碰到是其中選擇器的 specificity ,也就是常見的四個零,不過我覺得了解整個屬性值套用計算的過程十分有趣,有空也可以研究看看~感謝看到這裡的你,我們明天見~

/images/emoticon/emoticon42.gif

參考資料:

Assigning property values, Cascading, and Inheritance


以上的部分有任何錯誤的地方,歡迎指正呦~非常感謝~~XD


上一篇
多瞭解一點選擇器~(下)偽類、偽元素
下一篇
話說 CSS 規範的版本和狀態怎麼看呢?
系列文
每天來點 CSS Specification30

尚未有邦友留言

立即登入留言