@layer

Baseline 已廣泛支援

此特性已經十分成熟,可在許多裝置和瀏覽器版本上使用。自 2022 年 3 月起,它已在各瀏覽器中可用。

@layer CSS @規則用於宣告級聯層,也可用於定義多個級聯層時的優先順序順序。

試一試

@layer module, state;

@layer state {
  .alert {
    background-color: brown;
  }
  p {
    border: medium solid limegreen;
  }
}

@layer module {
  .alert {
    border: medium solid violet;
    background-color: yellow;
    color: white;
  }
}
<p class="alert">Beware of the zombies</p>

語法

css
/* statement at-rules */
@layer layer-name;
@layer layer-name, layer-name, layer-name;

/* block at-rules */
@layer {rules}
@layer layer-name {rules}

其中

layer-name

是級聯層的名稱。

rules

是級聯層中的 CSS 規則集。

描述

級聯層內的規則一起級聯,從而讓 Web 開發人員對級聯有更多的控制。未在層中定義的樣式總是會覆蓋在命名層和匿名層中宣告的樣式。

下圖顯示了層優先順序,其中層按 1, 2, ..., N 的順序宣告。

Diagram showing cascade layer priorities

如上圖所示,重要宣告(帶有 !important 標誌的宣告)優先於普通宣告(沒有 !important 標誌的常規宣告)。重要規則之間的優先順序順序與普通規則相反。過渡具有最高優先順序。接下來按從高到低的優先順序順序是重要的使用者代理宣告、重要使用者宣告和重要作者宣告;按此順序。使用者可以使用瀏覽器偏好設定、作業系統偏好設定或瀏覽器擴充套件來指定樣式。其重要宣告優先於作者(或Web開發人員編寫的)重要宣告。

在作者樣式中,CSS 層內的所有重要宣告都優先於在層外宣告的任何重要宣告,而 CSS 層內的所有普通宣告的優先順序都低於在層外宣告的宣告。宣告順序很重要。第一個宣告的層獲得最低優先順序,最後一個宣告的層獲得最高優先順序。但是,當使用!important 標誌時,優先順序會反轉。

@layer @規則可以透過以下三種方式之一建立級聯層。

第一種方法是使用 @layer 塊 @規則建立一個命名級聯層,其中包含該層的 CSS 規則,如下所示:

css
@layer utilities {
  .padding-sm {
    padding: 0.5rem;
  }

  .padding-lg {
    padding: 0.8rem;
  }
}

第二種方法是使用 @layer 語句 @規則建立一個或多個逗號分隔的命名級聯層,而不分配任何樣式。這可以是一個單獨的層,如下所示:

css
@layer utilities;

可以一次定義多個層,如下所示:

css
@layer theme, layout, utilities;

這很有用,因為層宣告的初始順序指示哪個層具有優先權。與宣告一樣,如果宣告出現在多個層中,則列表中最後一個層將獲勝。因此,對於前面的示例,如果在 themeutilities 中找到衝突的規則,則 utilities 中的規則將獲勝並被應用。

utilities 中的規則將被應用,即使它的特異性低於 theme 中的規則。這是因為一旦建立了層順序,特異性和出現順序就會被忽略。這使得可以使用更簡單的 CSS 選擇器,因為您不必確保選擇器具有足夠高的特異性來覆蓋衝突的規則;您只需確保它出現在後面的層中。

注意:宣告層名稱並設定其順序後,您可以透過重新宣告名稱將 CSS 規則新增到層中。然後,樣式將附加到層中,並且層順序不會更改。

第三種方法是使用不包含層名稱的 @layer 塊 @規則建立匿名層。例如:

css
@layer {
  p {
    margin-block: 1rem;
  }
}

這會建立一個匿名級聯層。此層的功能與命名層相同;但是,以後不能為其分配規則。匿名層的優先順序順序是層(命名或未命名)宣告的順序,並且低於在層外宣告的樣式。

建立級聯層的另一種方法是使用 @import。在這種情況下,規則將位於匯入的樣式表中。請記住,@import @規則必須位於所有其他型別的規則之前,除了 @charset@layer 規則。

css
@import "theme.css" layer(utilities);

巢狀層

層可以巢狀。例如:

css
@layer framework {
  @layer layout {
  }
}

要將規則附加到 framework 內的 layout 層,請將這兩個名稱用 . 連線起來。

css
@layer framework.layout {
  p {
    margin-block: 1rem;
  }
}

正式語法

@layer = 
@layer <layer-name>? { <rule-list> } |
@layer <layer-name># ;

<layer-name> =
<ident> [ '.' <ident> ]*

示例

基本示例

在以下示例中,建立了兩個 CSS 規則。一個用於任何層之外的 <p> 元素,另一個用於名為 type 的層中用於 .box p

沒有層的情況下,選擇器 .box p 將具有最高的特異性,因此文字 Hello, world! 將顯示為綠色。由於 type 層位於用於儲存非層內容的匿名層之前,因此文字將顯示為紫色。

另請注意順序。即使我們首先宣告非分層樣式,它仍然在分層樣式之後應用。

HTML

html
<div class="box">
  <p>Hello, world!</p>
</div>

CSS

css
p {
  color: rebeccapurple;
}

@layer type {
  .box p {
    font-weight: bold;
    font-size: 1.3em;
    color: green;
  }
}

結果

將規則分配給現有層

在以下示例中,建立了兩個沒有應用規則的層,然後將 CSS 規則應用於這兩個層。base 層定義了 colorborderfont-sizepaddingspecial 層定義了不同的顏色。由於在定義層時 special 層最後出現,因此它提供的顏色被使用,文字使用 rebeccapurple 顯示。來自 base 的所有其他規則仍然適用。

HTML

html
<div class="item">
  I am displayed in <code>color: rebeccapurple</code> because the
  <code>special</code> layer comes after the <code>base</code> layer. My green
  border, font-size, and padding come from the <code>base</code> layer.
</div>

CSS

css
@layer base, special;

@layer special {
  .item {
    color: rebeccapurple;
  }
}

@layer base {
  .item {
    color: green;
    border: 5px solid green;
    font-size: 1.3em;
    padding: 0.5em;
  }
}

結果

規範

規範
CSS 級聯與繼承第五級
# 分層

瀏覽器相容性

另見