# Cascade Layers

<figure><img src="https://3433349642-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FfNa3cQXA0JgS2aeBbzYg%2Fuploads%2Fy8uAtp1lsM9RrXsQUle7%2F%E6%88%AA%E5%9C%96%202023-05-30%20%E4%B8%8B%E5%8D%889.54.24.png?alt=media&#x26;token=f7ca7f19-89ba-4e6b-abef-92e3b0dd031f" alt=""><figcaption><p>目前主流瀏覽器皆可使用</p></figcaption></figure>

### 起源

以往 CSS 的管理，只能依靠撰寫者的功力制定規範區分 CSS 的使用與權重，更進階的則會使用例如使用 BEM、OOCSS 等方式，但仍舊需要在意權重，導致 CSS 的 .selector 越加越多、權重越來越重已經分不清到底是誰重了。為了解決這樣的問題，CSS 被發明出一種新的「權重」方式，叫做 Cascade Layers 。

### 觀念

優先判斷 Cascade Layers 權重，再判斷一般 CSS 權重。

### 用法

<pre class="language-css"><code class="lang-css">/* 直接寫內容，順序由上而下 */
@layer layera {
    .selector {}
}

@layer layerb {
    .selector {}
}


/* 先定義順序，再補充內容，寫了內容再定義順序是無效的！ */
@layer layera, layerb;

@layer layerb {
    .selector {}
}

@layer layera {
    .selector {}
}


/* 可巢狀 */
<strong>@layer layera {
</strong>    @layer layerb {
        .selector {}
    }
}

/* 也可以將名稱連接起來改變巢狀內的屬性 */
@layer layera.layerb {
    .selector {}
}

/* 也可以用 import 外部 css 的方式，並且命名 layer 名稱 */
@import url(demo.css) layer(layera);

/* 媒體查詢，有符合條件，layer才有定義 */
@media (min-width: 600px) {
   @layer layera {
     .selector {}
   }
 }
 
@media (prefers-color-scheme: dark) {
  @layer layerb {
     .selector {}
   }
}

</code></pre>

### 優先採用順序規則

#### 1. 沒有被放進去圖層的永遠最優先使用，不管一般權重

{% embed url="<https://codepen.io/neillin1023/pen/OJBYaMa>" %}

#### 2. 在都有 @layers 的情況，越後面寫的優先度越高，不管有沒有名稱跟一般權重

{% embed url="<https://codepen.io/neillin1023/pen/VwEOVay>" %}

#### 3. @layers 裡的屬性如果有 !important，則哪一個 cascade layer 裡的屬性有 !important 先被讀到就先贏

其真正原理其實是採用順序變成顛倒，但可以簡化成標題那樣的說法，為什麼呢？

首先，先觀看規則 1 的範例，根據規則 1 與 2 ，優先採用的順序是：\
沒有放入@layer的 > @layer theme > @layer base

如果我們只將 @layer base 裡的 color 屬性，加上 !important，則優先採用的順序：

@layer base > @layer theme >沒有放入@layer的

同理，如果我們只將 theme 裡的 color 屬性，加上 !important，則優先採用的順序：

@layer theme > @layer base >沒有放入@layer的

如果我們同時將 base 和 theme 裡的 color 屬性，加上 !important，則優先採用的順序：

@layer base > @layer theme >沒有放入@layer的

如果我們把三個的 color 都加上 !important，則優先採用的順序：

@layer base > @layer theme >沒有放入@layer的

因為原本 theme 會優先於 base，所以當都有 !important 時，base 反而優先於 theme。

如此，我們便可以得知，只要其中一個 layer 裡的 color 有 !important，經過顛倒之後， 沒有放入@layer 的肯定是順位最低。

再來，因為原本的優先順序是後寫的優先，經過顛倒之後，不管是先寫的、後寫的或是兩者裡面的 color，只要有加上 !important 而且是最先出現的，優先順序最高。

{% embed url="<https://codepen.io/neillin1023/pen/YzJbRpa>" %}

{% hint style="info" %}
也就是說，在導入 Cascade Layers 時，因為已經不是直覺上設定 !important 就一定會出現你要的結果。

不過正確來說，非緊急狀況，本來就不應該隨意使用 !important。

所以導入 Cascade Layers ，就是要更加慎重考慮使用 !important 的時機
{% endhint %}

#### 4. 如果重複寫了同樣的 Layer ，若有不同屬性將依照繼承規則，若有同屬性，則以一般權重判斷

{% embed url="<https://codepen.io/neillin1023/pen/ExdzOzo>" %}

#### 5. 巢狀則外層大於內層

{% embed url="<https://codepen.io/neillin1023/pen/zYmQyYp>" %}

#### 6. inline 大於一切

{% embed url="<https://codepen.io/neillin1023/pen/vYVwvKw>" %}

### 小結

隨著 Cascade Layers 的出現，CSS 的管理方法將再一次顛覆，但目前大家都還在嘗試中，所以也還不成熟。

以下附上 css-trick 的完整優先順序：

<figure><img src="https://css-tricks.com/wp-content/uploads/2022/02/layers-tall-outlines2.svg" alt="" width="563"><figcaption></figcaption></figure>

### 作業

請試著自己寫看看本篇所有的範例，印象才會比較深刻。

### 參考連結

* <https://ishadeed.com/article/cascade-layers/#less-worrying-about-specificity-issues>
* <https://caniuse.com/css-cascade-layers>
* <https://blog.yuyansoftware.com.tw/2022/02/css-cascade-layers-specificity/>
* <https://developer.mozilla.org/en-US/docs/Learn/CSS/Building_blocks/Cascade_layers>
* <https://pjchender.dev/css/css-cascade-and-layer/>
* <https://medium.com/starbugs/fa44a1462508>
* <https://z.itpub.net/article/detail/80C1B6025986B1CEFD490FE2DED389F8>
