跳至主要内容

[CSS] Cascade and Layer

keywords: css

資料來源

Cascade

Introducing the CSS Cascade @ MDN

  • Cascade 指的是針對同一個 HTML element 有多個不同的 CSS 樣式時,判斷要套用哪一個樣式的順序,判斷順序的邏輯稱作 cascade algorithm(由最上面的開始判斷,相同的話在往下):

    • Relevance:是不是相關的 HTML Element,有沒有符合特定的 condition(例如 media query)

    • Origin and importance:有沒有下 !important;是屬於 User-agent Style(瀏覽器)、Author Style(開發者)或 User style(瀏覽器的使用者)

      • transitions > !important (order reverse) > animations > inline-style > unlayered styles > layered styles
      • author > user > user-agent
      • 如果使用了 !important,則會和原本的權重反轉,變成 user-agent > user > author
    • Specificity

    • Order of appearance:出現的順序,越後面出現的會覆蓋前面出現過的

  • 比較的的順序會先判斷 cascade,一樣的話才會判斷 specificy,也就是說,即使某個 CSS selector 的 specificity 比較高,但 cascade 比較低的話,它還是會被其他 cascade 更高的所覆蓋:

    <head>
    <style>
    p {
    border: 3px solid blue;
    }

    /* 雖然 specificity 較高,但因為 cascade 較低,因此這裡的樣式最終會被覆蓋 */
    div p {
    border: 3px solid red;
    }
    </style>
    </head>

    <body>
    <div>
    <!-- 雖然 specificity 較低,但 inline-style 的 cascade 較高,因此最終會套用這裡的樣式 -->
    <p style="border: 3px solid green;">
    What the border color will be?
    </p>
    </div>
    </body>
  • 透過開發者工具(dev tool)可以檢視 CSS Cascade 的高低,越上面的表示順位越高

    CSS Cascade

Layers

@layer @ MDN

透過 layer,提供了開發者一個操作和改變 cascade 的機會。

/* named layer */
@layer layer-name { rules };

/* anonymous layer */
@layer { rules };

/* define layer and could append rules later */
@layer layer-name;

/* define multiple layers with specific "order", laster-declared layers win */
@layer layer-name, layer-name, layer-name;

/* create layer by using @import, the layer name will be "utilities" */
@import 'theme.css' layer(utilities);
提示

記得 layer-name 前後「不用」加上引號。

任何不在 layer 中的樣式都將被放到一個 anonymous layer 中,並在置於其他 declared layers, named, anonymous layers 之後,也就是說,在不考慮 specificity 的情況下,所有在 layer 外所定義的樣式都能覆蓋寫在 layer 內的樣式。

因此,如果是這樣寫:

<style>

@layer foobar {
/* 雖然 specificity 較高,但因為 cascade 較低,因此這裡的樣式最終會被覆蓋 */
body article figure p {
border: 3px solid red;
}
}

p {
border: 3px solid blue;
}
</style>