Tailwind CSS 客製化配置與最佳實踐 – 基礎測驗
測試你對 Tailwind 配置和最佳實踐的理解
當你開始在真實專案中使用 Tailwind CSS 時,很快就會遇到「預設的設計系統不完全符合需求」的情況。這時候,你需要知道如何客製化 Tailwind 的配置。本篇將帶你了解配置檔案的架構、如何自訂設計系統,以及撰寫 Tailwind CSS 專案的最佳實踐。
配置檔案:v3 vs v4 的差異
在開始之前,先了解 Tailwind CSS 在 v4.0 有重大變化:從 JavaScript 配置轉向 CSS-first 配置。
Tailwind v3:tailwind.config.js
在 v3 中,所有客製化都在 tailwind.config.js 進行:
// tailwind.config.js (v3)
module.exports = {
content: ['./src/**/*.{html,js,jsx,ts,tsx}'],
theme: {
extend: {
colors: {
brand: '#5046e5',
},
},
},
plugins: [],
}
Code language: JavaScript (javascript)
Tailwind v4:CSS-first 配置
v4.0 改為在 CSS 檔案中直接配置,使用 @theme 指令:
/* app.css (v4) */
@import "tailwindcss";
@theme {
--color-brand: #5046e5;
--font-display: "Inter", sans-serif;
}
Code language: CSS (css)
讀程式碼時,如果看到 tailwind.config.js,這是 v3 專案;如果看到 CSS 中的 @theme,這是 v4 專案。兩種方式都還被支援,但 v4 推薦使用 CSS-first 方式。
本文會同時介紹兩種方式,讓你能讀懂不同版本的專案。
自訂顏色:擴展 vs 覆蓋
最常見的客製化需求是添加品牌顏色。
擴展預設調色盤(推薦)
使用 extend 可以保留 Tailwind 預設的所有顏色,只新增你需要的:
// tailwind.config.js (v3)
module.exports = {
theme: {
extend: {
colors: {
brand: {
50: '#eff6ff',
100: '#dbeafe',
500: '#3b82f6',
600: '#2563eb',
700: '#1d4ed8',
},
},
},
},
}
Code language: JavaScript (javascript)
/* app.css (v4) */
@theme {
--color-brand-50: #eff6ff;
--color-brand-100: #dbeafe;
--color-brand-500: #3b82f6;
--color-brand-600: #2563eb;
--color-brand-700: #1d4ed8;
}
Code language: CSS (css)
這樣你就可以使用 bg-brand-500、text-brand-700 等 class。
覆蓋預設調色盤
如果你想完全控制可用的顏色,可以覆蓋整個 colors:
// tailwind.config.js (v3) - 覆蓋模式
module.exports = {
theme: {
// 注意:不在 extend 裡面!
colors: {
black: '#000',
white: '#fff',
primary: '#5046e5',
secondary: '#64748b',
},
},
}
Code language: JavaScript (javascript)
覆蓋後,預設的 red、blue、green 等顏色都不能用了,只能使用你定義的顏色。
判斷方式: 看設定是在 theme.extend 還是直接在 theme 下:
theme.extend.colors:擴展,保留預設theme.colors:覆蓋,取代預設
自訂間距系統
間距(spacing)影響 padding、margin、gap、width、height 等多個屬性。
新增特定間距值
// tailwind.config.js (v3)
module.exports = {
theme: {
extend: {
spacing: {
'18': '4.5rem', // 72px
'128': '32rem', // 512px
},
},
},
}
Code language: JavaScript (javascript)
/* app.css (v4) */
@theme {
--spacing-18: 4.5rem;
--spacing-128: 32rem;
}
Code language: CSS (css)
現在可以使用 p-18、w-128、mt-18 等 class。
間距的計算邏輯
Tailwind 預設間距是 4px 為基準:
spacing-1= 0.25rem = 4pxspacing-4= 1rem = 16pxspacing-8= 2rem = 32px
當你看到 p-4,知道這是 16px;看到 m-8,知道這是 32px。
自訂字型
新增字型家族
// tailwind.config.js (v3)
module.exports = {
theme: {
extend: {
fontFamily: {
display: ['Inter', 'sans-serif'],
body: ['Noto Sans TC', 'sans-serif'],
},
},
},
}
Code language: JavaScript (javascript)
/* app.css (v4) */
@theme {
--font-display: "Inter", sans-serif;
--font-body: "Noto Sans TC", sans-serif;
}
Code language: JavaScript (javascript)
使用方式:font-display、font-body。
自訂字型大小
// tailwind.config.js (v3)
module.exports = {
theme: {
extend: {
fontSize: {
'xxs': '0.625rem', // 10px
'display': '4.5rem', // 72px
},
},
},
}
Code language: JavaScript (javascript)
自訂斷點(Breakpoints)
預設斷點:sm: 640px、md: 768px、lg: 1024px、xl: 1280px、2xl: 1536px。
新增或修改斷點
// tailwind.config.js (v3)
module.exports = {
theme: {
extend: {
screens: {
'xs': '475px', // 新增更小的斷點
'3xl': '1920px', // 新增超大螢幕
},
},
},
}
Code language: JavaScript (javascript)
/* app.css (v4) */
@theme {
--breakpoint-xs: 475px;
--breakpoint-3xl: 1920px;
}
Code language: CSS (css)
@apply 指令:提取重複樣式
@apply 讓你在 CSS 中使用 Tailwind 的 utility class:
/* components.css */
.btn {
@apply px-4 py-2 rounded-lg font-medium transition-colors;
}
.btn-primary {
@apply btn bg-blue-600 text-white hover:bg-blue-700;
}
.btn-secondary {
@apply btn bg-gray-200 text-gray-800 hover:bg-gray-300;
}
Code language: JavaScript (javascript)
何時使用 @apply
適合使用的情況:
- 跨多個元件的重複樣式:當相同的 class 組合在多處出現且無法用元件抽象
- 第三方元件的基礎樣式:無法控制 HTML 結構時
- 全域表單元素樣式:如 input、button 的基礎樣式
/* 適合:全域的 input 樣式 */
.form-input {
@apply w-full px-3 py-2 border border-gray-300 rounded-md
focus:outline-none focus:ring-2 focus:ring-blue-500;
}
Code language: JavaScript (javascript)
何時避免 @apply
不建議使用的情況:
- 只是為了讓 HTML 看起來更乾淨:這樣做會失去 Tailwind 的優勢
- 只在單一地方使用的樣式:直接寫在 HTML 更直觀
- 可以用元件抽象的情況:React/Vue 元件比 CSS class 更好維護
/* 不推薦:單一用途的樣式 */
.hero-title {
@apply text-4xl font-bold text-center mb-8; /* 只用在一個地方 */
}
/* 不推薦:過度抽象 */
.card {
@apply bg-white rounded-lg shadow-md p-6;
}
.card-header {
@apply text-xl font-semibold mb-4;
}
.card-body {
@apply text-gray-600;
}
/* 這些應該用 React/Vue 元件來處理 */
Code language: JavaScript (javascript)
@apply 的最佳實踐
/* 好的做法:真正需要重用的基礎樣式 */
@layer components {
.btn {
@apply inline-flex items-center justify-center
px-4 py-2 rounded-lg font-medium
transition-colors duration-200
focus:outline-none focus:ring-2 focus:ring-offset-2;
}
}
Code language: JavaScript (javascript)
使用 @layer components 確保樣式放在正確的層級,可以被 utility class 覆蓋。
官方插件
Tailwind 提供幾個官方插件來擴展功能。
@tailwindcss/typography
為文章內容提供優美的排版樣式,特別適合 Markdown 轉換的內容:
v3 安裝:
// tailwind.config.js
module.exports = {
plugins: [
require('@tailwindcss/typography'),
],
}
Code language: JavaScript (javascript)
v4 安裝:
/* app.css */
@import "tailwindcss";
@plugin "@tailwindcss/typography";
Code language: CSS (css)
使用方式:
<article class="prose lg:prose-xl dark:prose-invert">
<!-- Markdown 內容會自動套用排版樣式 -->
<h1>文章標題</h1>
<p>這是段落內容...</p>
<ul>
<li>項目一</li>
<li>項目二</li>
</ul>
</article>
Code language: HTML, XML (xml)
prose class 會自動為:
- 標題設定適當的字級和間距
- 段落設定舒適的行高
- 清單、引用區塊、程式碼區塊都有合適的樣式
@tailwindcss/forms
為表單元素提供基礎樣式重置:
v3 安裝:
// tailwind.config.js
module.exports = {
plugins: [
require('@tailwindcss/forms'),
],
}
Code language: JavaScript (javascript)
v4 安裝:
/* app.css */
@import "tailwindcss";
@plugin "@tailwindcss/forms";
Code language: CSS (css)
安裝後,<input>、<select>、<textarea> 會有一致的基礎樣式,更容易用 Tailwind class 客製化。
策略選項:
/* v4 - 只在有 class 時套用 */
@plugin "@tailwindcss/forms" {
strategy: "class";
}
Code language: CSS (css)
strategy: "base":全域套用(預設)strategy: "class":需要加上form-input、form-select等 class 才套用
效能優化
自動 Tree Shaking(JIT 模式)
從 Tailwind v3 開始,JIT(Just-in-Time)模式成為預設。它只會產生你實際使用到的 CSS class,不需要手動配置 PurgeCSS。
你需要做的是確保 content 配置正確:
// tailwind.config.js (v3)
module.exports = {
content: [
'./src/**/*.{js,ts,jsx,tsx}',
'./pages/**/*.{js,ts,jsx,tsx}',
'./components/**/*.{js,ts,jsx,tsx}',
],
}
Code language: JavaScript (javascript)
注意動態 class 名稱
JIT 透過掃描檔案來決定要產生哪些 class,所以動態組合的 class 名稱會失效:
// 錯誤:JIT 掃描不到完整的 class 名稱
const color = 'red';
<div className={`bg-${color}-500`} />
// 正確:使用完整的 class 名稱
const colorClass = {
red: 'bg-red-500',
blue: 'bg-blue-500',
};
<div className={colorClass[color]} />
Code language: JavaScript (javascript)
最佳實踐總結
1. Class 排序
使用 prettier-plugin-tailwindcss 自動排序 class:
npm install -D prettier prettier-plugin-tailwindcss
排序後的 class 更容易閱讀:
<!-- 排序前:雜亂 -->
<div class="p-4 flex bg-white items-center rounded-lg shadow-md justify-between">
<!-- 排序後:有邏輯順序 -->
<div class="flex items-center justify-between rounded-lg bg-white p-4 shadow-md">
Code language: HTML, XML (xml)
2. 元件化思維
優先使用框架元件來處理重複的 UI,而非 @apply:
// React 元件 - 推薦
function Button({ variant = 'primary', children, ...props }) {
const variants = {
primary: 'bg-blue-600 text-white hover:bg-blue-700',
secondary: 'bg-gray-200 text-gray-800 hover:bg-gray-300',
};
return (
<button
className={`px-4 py-2 rounded-lg font-medium ${variants[variant]}`}
{...props}
>
{children}
</button>
);
}
Code language: JavaScript (javascript)
3. 避免過度抽象
不要為了「看起來乾淨」而抽象出一堆自訂 class:
/* 過度抽象 - 不推薦 */
.container-main { @apply max-w-7xl mx-auto px-4; }
.title-lg { @apply text-2xl font-bold; }
.mt-section { @apply mt-8; }
.text-muted { @apply text-gray-500; }
Code language: JavaScript (javascript)
這樣做會:
- 增加學習成本(團隊成員要學習你的自訂 class)
- 失去 Tailwind 的可預測性
- 增加維護負擔
4. 合理使用 arbitrary values
當內建值不夠用時,使用方括號語法:
<!-- 偶爾使用 - OK -->
<div class="w-[327px] h-[180px]">
<!-- 頻繁使用同樣的值 - 應該加到配置中 -->
<!-- 改為在 config 中定義 spacing 或 size -->
Code language: HTML, XML (xml)
實作練習:建立專案設計系統
以下是一個完整的客製化配置範例:
// tailwind.config.js (v3)
module.exports = {
content: ['./src/**/*.{js,ts,jsx,tsx}'],
theme: {
extend: {
colors: {
brand: {
50: '#f0f9ff',
100: '#e0f2fe',
200: '#bae6fd',
300: '#7dd3fc',
400: '#38bdf8',
500: '#0ea5e9',
600: '#0284c7',
700: '#0369a1',
800: '#075985',
900: '#0c4a6e',
},
},
fontFamily: {
sans: ['Inter', 'Noto Sans TC', 'sans-serif'],
},
spacing: {
'18': '4.5rem',
'88': '22rem',
},
borderRadius: {
'4xl': '2rem',
},
},
},
plugins: [
require('@tailwindcss/typography'),
require('@tailwindcss/forms'),
],
}
Code language: JavaScript (javascript)
/* app.css (v4 等效配置) */
@import "tailwindcss";
@plugin "@tailwindcss/typography";
@plugin "@tailwindcss/forms";
@theme {
--color-brand-50: #f0f9ff;
--color-brand-100: #e0f2fe;
--color-brand-200: #bae6fd;
--color-brand-300: #7dd3fc;
--color-brand-400: #38bdf8;
--color-brand-500: #0ea5e9;
--color-brand-600: #0284c7;
--color-brand-700: #0369a1;
--color-brand-800: #075985;
--color-brand-900: #0c4a6e;
--font-sans: "Inter", "Noto Sans TC", sans-serif;
--spacing-18: 4.5rem;
--spacing-88: 22rem;
--radius-4xl: 2rem;
}
Code language: CSS (css)
讀程式碼時的重點
當你在閱讀 Tailwind 專案時,注意以下模式:
- 看配置檔案位置:
tailwind.config.js= v3 配置- CSS 中的
@theme= v4 配置
- 判斷擴展還是覆蓋:
theme.extend.xxx:新增,保留預設theme.xxx:覆蓋,取代預設
- 看 @apply 使用情況:
- 少量、有意義的抽象 = 好的實踐
- 大量、瑣碎的抽象 = 過度使用
- 看 content 配置:
- 確認所有使用 Tailwind 的檔案都被涵蓋
- 漏掉會導致樣式不生效
總結
本篇介紹了 Tailwind CSS 的客製化配置與最佳實踐:
| 主題 | 重點 |
|---|---|
| 配置方式 | v3 用 JS 配置、v4 用 CSS-first |
| 擴展 vs 覆蓋 | extend 保留預設、直接設定則覆蓋 |
| @apply | 用於真正需要重用的樣式,避免過度使用 |
| 官方插件 | typography 用於文章、forms 用於表單 |
| 最佳實踐 | class 排序、元件化、避免過度抽象 |
這是 Tailwind CSS 教學系列的最後一篇。透過這四篇文章,你已經掌握了閱讀 Tailwind 專案所需的核心知識:基礎語法、響應式設計、Flexbox/Grid 布局,以及客製化配置。當你在實際專案中遇到 Tailwind 程式碼時,這些知識將幫助你快速理解專案的設計系統和樣式架構。
Tailwind CSS 客製化配置與最佳實踐 – 進階測驗
情境題與錯誤診斷,測試你的實戰能力
.btn 的樣式被 utility class 難以覆蓋?
/* styles.css */
@tailwind base;
@tailwind components;
@tailwind utilities;
.btn {
@apply px-4 py-2 bg-blue-600 text-white rounded-lg;
}.page-container { @apply max-w-7xl mx-auto px-4; }
.section-title { @apply text-2xl font-bold mb-4; }
.section-subtitle { @apply text-lg text-gray-600 mb-2; }
.mt-sm { @apply mt-2; }
.mt-md { @apply mt-4; }
.mt-lg { @apply mt-8; }
.text-muted { @apply text-gray-500; }
.text-primary { @apply text-blue-600; }bg-brand-500?
/* app.css */
@import "tailwindcss";
@theme {
--brand-50: #f0f9ff;
--brand-500: #0ea5e9;
--brand-900: #0c4a6e;
}