CSS @layer 階層管理 (Cascade Layers)

CSS 階層管理 (@layer) 是 CSS 重大的革新功能,它提供了一種全新的方式來控制 CSS 的疊加權重(Specificity),幫助開發者解決「權重地獄」的問題。

什麼是 @layer?

在傳統 CSS 中,樣式的優先權是由「權重 (Specificity)」和「出現順序 (Order)」決定的。這往往導致開發者為了覆寫某個樣式,不得不使用更複雜的選擇器(例如 .main .content .article p)甚至是 !important

@layer 允許你將樣式分組到不同的「層級」中,並顯式地定義層級之間的優先順序。層級的優先順序高於選擇器的權重。

定義與使用方式

你可以使用 @layer 關鍵字來宣告一個層級。

@layer base, components, utilities;

@layer base {
  a {
    color: blue;
  }
}

@layer components {
  .button {
    color: white;
    background: black;
  }
}

優先權規則

  1. 後定義的層級勝出:在 @layer base, components; 中,components 層的樣式會覆寫 base 層,不論選擇器的權重如何
  2. 無層級樣式 (Unlayered) 最強:任何不屬於特定 @layer 的樣式,其優先權都高於所有 @layer 內的樣式。

層級排序

最佳實務是在 CSS 文件的最頂部預先定義好層級順序:

/* 預先定義順序:最左邊權限最低,最右邊權限最高 */
@layer reset, base, framework, components, utilities;

@layer framework {
  /* 即使這裡權能很高,也會被下面的層級覆寫 */
  .card {
    padding: 50px;
  }
}

@layer components {
  /* 這個樣式會勝出 */
  .card {
    padding: 20px;
  }
}

實務應用場景

整合第三方套件

當你使用外部元件庫(如 Bootstrap 或自定義的 UI Kit)時,可以用 @layer 將其包裹起來,確保你的自定義樣式始終能輕鬆覆寫套件內容。

/* 這行指令將整個 Bootstrap 框架匯入,並將其分配到一個名為 framework 的階層中 */
@import url('bootstrap.css') layer(framework);

/* 在 CSS Layers 的規則中,後定義的層級擁有較高的優先權 */
@layer custom {
  .btn {
    border-radius: 0; /* 輕鬆覆寫框架樣式 */
  }
}

模組化開發

透過將重置樣式、基礎排版、功能性類別(Utilities)分層,可以大幅減少樣式衝突。

層級嵌套 (Nested Layers)

層級可以互相嵌套,這讓你可以建立更精細的樣式階層體系。

使用點號 (.) 語法

你可以在外部直接定義嵌套層級的完整路徑:

/* 預先定義嵌套順序 */
@layer components.buttons, components.cards;

@layer components.buttons {
  .btn {
    border: 1px solid black;
  }
}

直接在內部嵌套

也可以在一個 @layer 區塊內部直接撰寫另一個 @layer

@layer components {
  @layer buttons {
    /* 這實際上代表 components.buttons */
    .btn {
      color: white;
    }
  }
}

嵌套層級的優先度

嵌套層級的優先順序僅在該父層級內部生效。例如,在 components 層級中,components.cards 若定義在 components.buttons 之後,則 cards 的樣式優先權較高。

注意事項

  • !important 的特殊行為:在 @layer 中使用 !important 會反轉優先順序(降低權限),這是一個為了確保層次結構一致性的技術細節,通常建議避免在 @layer 中使用它。

瀏覽器支援度

@layer 獲得了主流瀏覽器(Chrome 99+, Firefox 97+, Safari 15.4+)的全面支援,是目前管理大型專案 CSS 結構的最佳實務。

雖然你可以隨處定義 @layer,但為了管理上的清晰,強烈建議在專案的主 CSS 進入點文件(Entry point)頂端統一宣告所有層級的順序。