CSS Mixins 原生 @apply 取代 Sass 預處理器完整教學(2026 實戰指南)
老實說,我第一次聽到 CSS 要原生支援 Mixins 的時候,心裡是半信半疑的。畢竟我們用 Sass 寫 @mixin 和 @include 已經快十年了,突然說瀏覽器要內建這個功能?但事實證明,CSS 的進化速度真的超乎想像。今天我就來帶你完整了解 CSS 原生 Mixins 搭配 @apply 的用法,以及為什麼你可以開始考慮跟 Sass 說再見了。
CSS Mixins 是什麼?@mixin 和 @apply 語法介紹
如果你寫過 Sass,對 Mixin 的概念一定不陌生。簡單來說,Mixin 就是一組可以重複使用的樣式片段,你定義一次,然後在任何地方套用。過去這是 Sass 的專利,但現在 CSS 原生的 @mixin 和 @apply 規則讓我們不再需要編譯工具也能做到同樣的事。
CSS 原生 Mixin 的語法非常直覺:
@mixin --card-base {
border-radius: 12px;
padding: 1.5rem;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
background: white;
}
.product-card {
@apply --card-base;
border: 1px solid #e0e0e0;
}
.profile-card {
@apply --card-base;
border: 2px solid #3b82f6;
}你用 @mixin 定義一組樣式,名稱以雙破折號 -- 開頭(跟 CSS Custom Properties 的命名慣例一致),然後在需要的地方用 @apply 套用。就這麼簡單,不需要任何編譯步驟。
為什麼我們不再需要 Sass?原生 CSS 的進化
這幾年 CSS 的進化速度簡直像在坐火箭。回想一下,我們當初為什麼要用 Sass?無非就是這幾個原因:變數、巢狀選擇器、Mixins、模組化。但你看看現在的 CSS:
- 變數 — CSS Custom Properties(
--color-primary)早就穩定支援了 - 巢狀 — CSS Nesting 已經全面落地
- Mixins — 就是我們今天在講的
@mixin/@apply - 條件邏輯 — CSS 原生 If 條件邏輯也在推進中
說真的,Sass 最大的價值正在被原生 CSS 一項一項吃掉。我個人認為,對於新專案來說,已經沒有太強的理由繼續引入 Sass 了。少一個編譯步驟,少一個依賴,開發體驗反而更清爽。
實際程式碼範例:定義 Mixin 和套用
讓我們來看幾個實戰場景。第一個是最常見的按鈕樣式重用:
@mixin --btn-base {
display: inline-flex;
align-items: center;
justify-content: center;
padding: 0.75rem 1.5rem;
border-radius: 8px;
font-weight: 600;
cursor: pointer;
transition: all 0.2s ease;
}
.btn-primary {
@apply --btn-base;
background: #3b82f6;
color: white;
}
.btn-secondary {
@apply --btn-base;
background: transparent;
color: #3b82f6;
border: 2px solid #3b82f6;
}第二個範例是排版相關的 Mixin,這在設計系統裡特別好用:
@mixin --text-heading {
font-family: 'Noto Sans TC', sans-serif;
font-weight: 700;
line-height: 1.3;
letter-spacing: -0.02em;
}
@mixin --text-body {
font-family: 'Noto Sans TC', sans-serif;
font-weight: 400;
line-height: 1.75;
letter-spacing: 0.01em;
}
h1 { @apply --text-heading; font-size: 2.5rem; }
h2 { @apply --text-heading; font-size: 2rem; }
p { @apply --text-body; font-size: 1rem; }這種模式讓你的設計 Token 直接用 CSS 就能管理,搭配 Container Queries 響應式設計更是如虎添翼。
可以帶參數的 Mixin(Conditional Logic)
你可能會問:Sass 的 Mixin 可以帶參數啊,原生 CSS 能做到嗎?答案是可以的,而且做法更優雅——透過 CSS Custom Properties 來實現。
@mixin --flexible-grid {
display: grid;
grid-template-columns: repeat(var(--cols, 3), 1fr);
gap: var(--grid-gap, 1rem);
}
.product-grid {
@apply --flexible-grid;
--cols: 4;
--grid-gap: 1.5rem;
}
.sidebar-grid {
@apply --flexible-grid;
--cols: 1;
--grid-gap: 0.75rem;
}這個技巧的精髓在於:Mixin 內部引用 Custom Properties 作為「參數」,套用時透過覆寫這些變數來改變行為。比 Sass 的參數語法更靈活,因為你可以在任何層級覆寫,包括媒體查詢裡面。
進階一點,你還可以結合 CSS 的條件邏輯來做更複雜的判斷:
@mixin --responsive-container {
width: 100%;
max-width: var(--container-max, 1200px);
margin-inline: auto;
padding-inline: var(--container-padding, 1rem);
}
.main-content {
@apply --responsive-container;
--container-max: 960px;
--container-padding: 2rem;
}瀏覽器支援狀況與 Fallback 策略
我知道你在想什麼——「這些東西瀏覽器到底支不支援?」截至 2026 年中,CSS Mixins 已經在 Chrome 126+、Edge 126+、Safari 18.2+ 和 Firefox 130+ 中獲得支援。換句話說,主流瀏覽器的最新版本都已經可以用了。
但如果你的專案需要支援稍舊的瀏覽器,fallback 策略也不難:
/* Fallback:直接寫基礎樣式 */
.card {
border-radius: 12px;
padding: 1.5rem;
background: white;
}
/* 支援 @apply 的瀏覽器會覆蓋 */
@supports (selector(&)) {
@mixin --card-enhanced {
border-radius: 12px;
padding: 1.5rem;
background: white;
box-shadow: 0 4px 12px rgba(0,0,0,0.08);
}
.card {
@apply --card-enhanced;
}
}用 @supports 做漸進增強,確保舊瀏覽器至少能看到基本樣式,新瀏覽器則享受完整的 Mixin 體驗。這也是做 View Transitions API 頁面轉場時常用的策略。
搭配 CSS Layers 和 Custom Properties 使用
CSS Mixins 真正的威力在於跟其他現代 CSS 功能搭配使用。特別是 CSS Layers(@layer)和 Custom Properties 的組合,可以打造出一套完整的設計系統架構。
@layer base, components, utilities;
@layer base {
@mixin --reset-spacing {
margin: 0;
padding: 0;
box-sizing: border-box;
}
@mixin --theme-colors {
--primary: #3b82f6;
--secondary: #8b5cf6;
--surface: #ffffff;
--text: #1e293b;
}
:root {
@apply --theme-colors;
}
* {
@apply --reset-spacing;
}
}
@layer components {
@mixin --card-component {
background: var(--surface);
color: var(--text);
border-radius: 12px;
padding: 1.5rem;
}
.card {
@apply --card-component;
}
}
@layer utilities {
@mixin --sr-only {
position: absolute;
width: 1px;
height: 1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
}
.sr-only {
@apply --sr-only;
}
}這個架構的好處是:Mixin 的定義和使用都被明確地分層了。Base layer 放重置和主題變數,Components layer 放元件樣式,Utilities layer 放工具類。層級的優先順序清楚明確,不會再出現 Sass 那種 import 順序搞混導致樣式覆蓋的問題。
從 Sass 遷移到原生 CSS Mixins 的建議
如果你正在考慮從 Sass 遷移,我的建議是不要一次全改。可以從新元件開始用原生 Mixins,舊的 Sass 檔案暫時保留。具體步驟:
- 盤點現有 Sass Mixins — 列出你專案裡所有的
@mixin,標記哪些可以直接用原生語法改寫 - 轉換簡單的 Mixin — 不帶參數或只用變數當參數的 Mixin,基本上可以一對一轉換
- 處理帶邏輯的 Mixin — 含有
@if、@each等邏輯的 Mixin,改用 Custom Properties + CSS 條件來實現 - 測試瀏覽器相容性 — 確認你的目標瀏覽器版本都支援
- 移除 Sass 依賴 — 確認所有功能正常後,拿掉
sass和相關 loader
整個過程可能需要幾週到幾個月,取決於專案規模。但做完之後你會發現,建置速度變快了,開發環境更簡潔了,而且 CSS 的可維護性其實更好。
結語:擁抱原生,告別工具鏈的束縛
CSS Mixins 的原生支援是前端開發的一個重要里程碑。它不只是取代 Sass 的某個功能而已,更代表著我們終於可以用純粹的 CSS 來建構完整的設計系統。搭配 Custom Properties、CSS Layers、Container Queries 和原生巢狀語法,現代 CSS 的表達能力已經不輸任何預處理器。
我的建議是:如果你還沒開始嘗試,現在就是最好的時機。從一個小專案開始,感受一下不用編譯、不用設定 loader、直接寫 CSS 的暢快感。你會發現,原來寫 CSS 可以這麼純粹。
繼續閱讀
CSS Popover API + Anchor Positioning 完整教學:原生打造零 JavaScript 的浮動 UI 元件
CSS Popover API 和 Anchor Positioning 是 2026 年前端最令人興奮的原生 API 組合。本文教你如何用純 CSS 打造 tooltip、dropdown menu 和浮動面板,徹底告別 Popper.js。
相關文章
CSS Popover API + Anchor Positioning 完整教學:原生打造零 JavaScript 的浮動 UI 元件
CSS Popover API 和 Anchor Positioning 是 2026 年前端最令人興奮的原生 API 組合。本文教你如何用純 CSS 打造 tooltip、dropdown menu 和浮動面板,徹底告別 Popper.js。
CSS light-dark() 函數完全指南:原生主題切換不再需要 JavaScript 2026
CSS light-dark() 函數是 2026 年最受矚目的 CSS 新特性之一,讓你無需一行 JavaScript 就能實現完整的深色/淺色主題切換系統。本文帶你從基礎到進階完整掌握這個強大的原生解決方案。
你可能也喜歡
探索其他領域的精選好文