瀑布

CSS Podcast - 004: The Cascade

CSS 是「Cascading Stylesheets」的縮寫。階層是用來解決衝突的演算法,當多個 CSS 規則套用至 HTML 元素時,就會發生衝突。因此,使用下列 CSS 設定樣式的按鈕文字會顯示為藍色。

button {
  color: red;
}

button {
  color: blue;
}

瞭解級聯演算法有助於您瞭解瀏覽器如何解決這類衝突。級聯演算法分為 4 個獨立階段。

  1. 顯示位置和順序:CSS 規則的顯示順序
  2. 特異性:用於判斷哪個 CSS 選取器最符合條件
  3. 來源:CSS 顯示的順序和來源,無論是瀏覽器樣式、瀏覽器擴充功能的 CSS 或您編寫的 CSS
  4. 重要性:部分 CSS 規則的權重高於其他規則,特別是 !important 規則類型

顯示位置和順序

階層會在計算衝突解決方案時,考量 CSS 規則的顯示順序和顯示方式。這是分層處理的最後一個步驟,一律會產生單一勝出的宣告。不過,只有在考量了所有級聯步驟後,系統仍會考量位置,因為這時可能仍有衝突的樣式。

本課程一開始的示範,就是最簡單的位置範例。有兩個作者來源規則沒有重要性,兩者都未分層,且來自具有相同特異性的選取器的規則,因此最後宣告的規則會勝出。

樣式可來自 HTML 頁面上的各種來源,例如 <link> 標記、嵌入的 <style> 標記、@import 規則,以及元素 style 屬性中定義的內嵌 CSS。

如果您在 HTML 頁面頂端的 <link> 中加入 CSS,然後在頁面底部的另一個 <link> 中加入 CSS,則底部 <link> 中的樣式優先順序會較高。嵌入的 <style> 元素或單一 style 屬性中的相衝突宣告也會發生同樣的情況。如果每個階層的步驟都相同,則最後一個樣式會勝出。

按鈕具有藍色背景,這是由 CSS 定義,並包含在 <link /> 元素中。在第二個連結的樣式表單中,有一個 CSS 規則會將其設為深色,並且會在較後的位置套用。

這項排序也適用於嵌入的 <style> 元素。如果是在 <link> 之前宣告,則連結的樣式表 CSS 會具有較高的優先順序。

<style> 元素會在 <head> 中宣告,而 <link /> 元素則會在 <body> 中宣告。也就是說,它比 <style> 元素更具體

style 屬性相關的選取器順序並不重要,因為這些衝突會在連鎖的元素附加步驟中解決。不過,同一個樣式屬性中的多個宣告仍可依靠位置決定勝出者。

位置也會依 CSS 規則的順序套用。在這個範例中,元素會採用紫色背景,因為 background: purple 是最後宣告的元素。由於綠色背景是在紫色背景之前宣告,因此瀏覽器會忽略綠色背景。

.my-element {
  background: green;
  background: purple;
}

針對相同屬性指定兩個值,是為不支援特定值的瀏覽器建立備用項的簡單方法。在下一個範例中,font-size 會宣告兩次。如果瀏覽器支援 clamp(),則系統會捨棄先前的 font-size 宣告。如果瀏覽器不支援 clamp(),系統會採用初始宣告,字型大小則會設為 1.5rem

.my-element {
  font-size: 1.5rem;
  font-size: clamp(1.5rem, 1rem + 3vw, 2rem);
}

進行隨堂測驗

測驗您對階層的瞭解

如果網頁上有下列 HTML:

<!DOCTYPE html>
<html lang="en">
  <head>
    <link rel="stylesheet" href="/styles.css" />
  </head>
  <body>
    <button>I am a button</button>
    <style>
      button {
        background: pink;
      }
    </style>
  </body>
</html>

styles.css 中包含以下 CSS 規則:

button {
  background: yellow;
}

按鈕的背景顏色為何?

粉紅色
嵌入的 <style> 來源比 <link> 標記更靠近網頁底部,因此雖然 button 的特定性相同,但樣式規則的位置會讓它勝出。
黃色
對 HTML 文件而言,黃色按鈕背景可能會先讀取,但之後發現有相同特異性的新規則,因此這個規則不會套用至按鈕。

優先權

特定性是一種演算法,可透過權重或評分系統計算,判斷哪個 CSS 選取器最為特定。透過更明確的規則,即使在 CSS 中出現與選取器相符的其他 CSS,您仍可套用該規則。

下一課中,您可以瞭解計算特異性的詳細方式,不過請記住以下幾點,以免產生太多特異性問題。

與只指定元素的 CSS 相比,CSS 指定元素上的類別會讓規則更具體,因此會被視為更重要的規則。也就是說,在使用下列 CSS 時,即使兩個規則都相符,且 h1 選取器的規則在樣式表中較後出現,h1 仍會以紅色顯示。

<h1 class="my-element">Heading</h1>
.my-element {
  color: red;
}

h1 {
  color: blue;
}

id 可讓 CSS 更具體化,因此套用至 ID 的樣式會覆寫以其他方式套用的樣式。這也是為何一般來說,不建議將樣式附加至 id 的原因之一。這可能會導致您難以將該樣式覆寫為其他樣式。

特異性會累積

您可以在下一課中瞭解,每種選取器都會獲得點數,用來表示其精確度,而您用來指定元素的所有選取器點數會加總。也就是說,如果您以選取器清單 (例如 a.my-class.another-class[href]:hover) 指定元素,就會很難透過其他 CSS 覆寫。因此,為了讓 CSS 更易於重複使用,建議您盡可能簡化選取器。在需要時,請使用特定性做為取得元素的工具,但請務必考慮重構長而特定的選取器清單。

來源

您撰寫的 CSS 並非網頁中唯一套用的 CSS。級聯會考量 CSS 的來源。這個來源包括瀏覽器的內部樣式表單、瀏覽器擴充功能或作業系統新增的樣式,以及您撰寫的 CSS。這些來源的特定性順序 (從最不精確到最精確) 如下:

  1. 使用者代理程式基本樣式。這些是瀏覽器預設套用至 HTML 元素的樣式。
  2. 本機使用者樣式。這些設定可能來自作業系統層級,例如基本字型大小,或減少動畫的偏好設定。這些內容也可能來自瀏覽器擴充功能,例如可讓使用者為網頁編寫自訂 CSS 的瀏覽器擴充功能。
  3. 作者 CSS。您編寫的 CSS。
  4. 作者 !important。您在自訂宣告中加入的任何 !important
  5. 本機使用者樣式 !important。任何來自作業系統層級或瀏覽器擴充功能層級 CSS 的 !important
  6. 使用者代理程式 !important。瀏覽器提供的預設 CSS 中定義的任何 !important

來源順序的視覺化示意圖,如清單中所述。

如果您在編寫的 CSS 中使用 !important 規則類型,而使用者在自訂 CSS 中使用 !important 規則類型,那麼誰的 CSS 會勝出?

進行隨堂測驗

測驗您對級聯來源的瞭解

測驗您對級聯來源的瞭解程度,請考慮下列來自不同來源的樣式規則:

使用者代理程式樣式

h1 { margin-block-start: 0.83em; }

啟動

h1 { margin-block-start: 20px; }

頁面作者樣式

h1 { margin-block-start: 2ch; }

@media (max-width: 480px) {
  h1 { margin-block-start: 1ch; }
}

使用者自訂樣式

h1 { margin-block-start: 2rem !important; }

接著,請提供下列 HTML:

<h1>Lorem ipsum</h1>

h1的最終 margin-block-start 是什麼?

20px
Bootstrap 是作者來源的一部分,但會失去重要的本機使用者樣式。
0.83em
使用者代理程式樣式來源會輸給重要的本機使用者樣式。
2rem
這個 !important 使用者自訂樣式具有最明確的來源。
2ch
這個作者樣式是作者來源的一部分,會輸給重要的本機使用者樣式。
1ch
這個作者樣式是作者來源的一部分,會輸給重要的本機使用者樣式。

重要性

並非所有 CSS 規則的計算方式都相同,也不一定具有相同的特定性。

重要性排序 (由低至高) 如下:

  1. 一般規則類型,例如 font-sizebackgroundcolor
  2. animation 規則類型
  3. !important 規則類型 (依來源順序)
  4. transition 規則類型

活動動畫和轉場效果規則類型的優先順序高於一般規則。轉換的重要性高於 !important 規則類型。這是因為當動畫或轉場效果啟用時,預期的行為是變更視覺狀態。

使用開發人員工具找出某些 CSS 未套用的原因

瀏覽器開發人員工具通常會顯示所有可能與元素相符的 CSS,並將未使用的 CSS 劃掉。

瀏覽器開發人員工具,其中已覆寫的 CSS 已劃掉。

如果您預期套用的 CSS 完全沒有顯示,表示該 CSS 與元素不符。在這種情況下,您需要尋找其他原因,例如類別或元素名稱的拼寫錯誤,或是無效的 CSS。

進行隨堂測驗

測驗您對階層的瞭解

Cascade 可用於...

在元素套用多種樣式時解決衝突。
這是其主要目標之一,即解決衝突。
確保在繪製期間,每個屬性只有一個樣式值。
文字只能使用一種顏色,而層疊是決定該使用哪一種顏色的一種方式。
評分和加權樣式規則。
評分和權重是 The Cascade 排序階段的一部分。
排序及篩選樣式屬性。
排序和篩選是 The Cascade 的階段,可協助您瞭解衝突解決的各個層面。

資源