CSS @layer 層疊圖層完整教學:終結樣式優先權大戰的終極武器
你有沒有遇過這種狀況:明明寫了正確的 CSS,但樣式就是不生效,最後只好在末尾加上 !important,然後過兩天又需要用另一個 !important 來覆蓋前一個?這場無止境的優先權大戰,CSS @layer 終於提供了根本性的解決方案。
什麼是 CSS @layer
CSS @layer(層疊圖層)是 CSS Cascade Level 5 規範中引入的功能,讓你可以明確定義樣式的優先順序。傳統的 CSS 優先權取決於選擇器權重(specificity)、來源順序和 !important,而 @layer 在這之上增加了一個新的維度——圖層順序。
簡單來說,後面宣告的圖層優先權高於前面的。這意味著你可以在最前面就決定好整個專案的樣式優先架構,不再被選擇器的權重牽著鼻子走。
三種宣告 @layer 的方式
你可以用三種方式建立和使用圖層:
方式一:直接定義順序
/* 越後面優先權越高 */
@layer reset, base, components, utilities;
這行程式碼一口氣宣告了四個圖層的優先順序。即使你之後在程式碼中以任何順序填入規則,順序都已經固定了。
方式二:區塊宣告
@layer base {
h1 { font-size: 2rem; color: #333; }
p { line-height: 1.8; }
}
@layer components {
.card h1 { font-size: 1.5rem; color: #111; }
}
方式三:匯入時指定圖層
@import url('reset.css') layer(reset);
@import url('bootstrap.css') layer(framework);
@import url('custom.css') layer(custom);
這個方式在整合第三方框架時超好用。你可以把整個 Bootstrap 放進一個圖層,確保你自己寫的樣式永遠贏過它。
圖層的優先權運作機制
@layer 的優先權規則其實很直覺:
- 圖層順序決定一切:後面宣告的圖層勝過前面的,無論選擇器權重多高。
- 同一圖層內:回歸正常的 specificity 規則。
- 未分層的樣式(unlayered):優先權高於所有已分層的樣式。
@layer base, components;
@layer base {
#main .content p.highlight { /* 權重超高 */
color: blue;
}
}
@layer components {
p { /* 權重超低 */
color: red;
}
}
/* 結果:文字是紅色!因為 components 圖層在 base 之後 */
這就是 @layer 革命性的地方——你不再需要用更高權重的選擇器去覆蓋樣式,圖層順序直接凌駕 specificity。
!important 的行為反轉
這是最容易讓人困惑的部分。在 @layer 中,!important 的優先權邏輯是反過來的:
@layer base, components;
@layer base {
p { color: blue !important; }
}
@layer components {
p { color: red !important; }
}
/* 結果:文字是藍色! */
為什麼?因為 !important 規則的圖層順序是反轉的。在正常情況下 components 勝出,但加了 !important 後,較早宣告的 base 反而優先。這個設計的意圖是讓底層的保護性樣式(如 reset)能用 !important 鎖定關鍵規則,不被上層覆蓋。
未分層樣式的陷阱
未分層的樣式(不在任何 @layer 裡面的)優先權最高,這是一把雙面刃:
@layer base, components;
@layer components {
.btn { background: blue; }
}
/* 未分層 - 優先權高於所有圖層 */
.btn { background: red; }
在實務上,我建議把所有樣式都放進圖層,只在極少數需要「絕對覆蓋」的情況才使用未分層樣式。否則就跟到處寫 !important 沒兩樣了。
大型專案的圖層架構設計
分享一個我在實際專案中使用的圖層架構:
/* 定義全站圖層優先順序 */
@layer reset, tokens, base, layout, components, patterns, utilities, overrides;
/* reset: CSS Reset / Normalize */
@layer reset {
*, *::before, *::after { box-sizing: border-box; margin: 0; }
}
/* tokens: Design Token / CSS 變數 */
@layer tokens {
:root {
--color-primary: #2563eb;
--color-secondary: #7c3aed;
--spacing-base: 0.5rem;
--font-sans: 'Inter', system-ui, sans-serif;
}
}
/* base: HTML 元素基礎樣式 */
@layer base {
body { font-family: var(--font-sans); line-height: 1.6; }
a { color: var(--color-primary); text-decoration: none; }
}
/* components: 元件樣式 */
@layer components {
.btn { padding: 0.5rem 1rem; border-radius: 0.375rem; }
.card { border: 1px solid #e5e7eb; border-radius: 0.75rem; }
}
/* utilities: 工具類 */
@layer utilities {
.text-center { text-align: center; }
.mt-4 { margin-top: 1rem; }
}
這個架構的好處是每個人都知道新樣式該放在哪一層,減少了團隊協作時的衝突。想深入了解如何用CSS 現代色彩函式來建構更彈性的 Design Token,可以參考我之前的文章。
搭配 Tailwind CSS v4 使用
Tailwind CSS v4 原生支援 @layer,而且它的圖層架構跟我們剛才討論的完全一致:
/* Tailwind v4 預設的圖層順序 */
@layer theme, base, components, utilities;
/* 你可以在 components 圖層中定義自訂元件 */
@layer components {
.btn-primary {
@apply bg-blue-600 text-white px-4 py-2 rounded-lg;
@apply hover:bg-blue-700 transition-colors;
}
}
Tailwind 的 utilities 圖層永遠在最上面,所以你在 HTML 中用的 utility class 一定能覆蓋 components 裡的樣式,完全不需要 !important。如果你正在使用 Tailwind CSS v4 的 Container Queries 功能,搭配 @layer 可以讓響應式元件的樣式管理更加乾淨。
要進一步了解如何善用 Tailwind CSS @apply 建立自訂元件,裡面有更詳細的元件封裝策略。
巢狀圖層與進階技巧
@layer 支援巢狀結構,適合大型設計系統:
@layer components {
@layer buttons {
.btn { /* 按鈕基礎樣式 */ }
}
@layer forms {
.input { /* 表單基礎樣式 */ }
}
}
/* 也可以用點號語法 */
@layer components.buttons {
.btn-icon { /* 圖示按鈕 */ }
}
搭配 SVG 動畫時,你可以把動畫相關的樣式放在獨立的圖層中,避免跟元件樣式互相干擾。
瀏覽器支援與遷移策略
好消息是 @layer 的瀏覽器支援已經很完整了。截至 2026 年,所有主流瀏覽器(Chrome 99+、Firefox 97+、Safari 15.4+、Edge 99+)都已支援,全球覆蓋率超過 95%。
如果你的專案需要支援舊瀏覽器,可以用 PostCSS 的 postcss-cascade-layers 外掛做降級處理。不過我建議新專案直接擁抱 @layer,因為它真的能從根本上改善 CSS 架構的可維護性。
總結
CSS @layer 不只是一個新語法,它代表了 CSS 架構思維的根本轉變。從「用更高的 specificity 蓋過去」變成「在正確的圖層放正確的規則」。對於任何中大型專案,我強烈建議在專案初期就規劃好圖層架構,這會為團隊省下無數除錯 CSS 的時間。記住:好的 CSS 架構不是沒有衝突,而是衝突發生時你知道規則會怎麼解決。
繼續閱讀
CSS Nesting 原生巢狀語法完全教學:告別預處理器的新時代
原生 CSS Nesting 語法完全教學,從基本語法到進階技巧,帶你告別 Sass 預處理器依賴。
相關文章
你可能也喜歡
探索其他領域的精選好文