主題系統
AppFuse Web 使用 Tailwind CSS 4 + DaisyUI 5 建構主題系統,支援 30+ 預設主題和自訂主題。
技術架構
預設主題
AppFuse Web 內建 Fusion 主題作為預設,另支援多種 DaisyUI 主題:
| 主題 | 說明 | 適用場景 |
|---|---|---|
| fusion | AppFuse 品牌主題(預設) | 企業應用 |
| light | 明亮主題 | 一般用途 |
| dark | 深色主題 | 低光環境 |
| garden | 花園主題 | 花店/園藝 |
| cupcake | 柔和粉彩 | 活潑風格 |
| valentine | 情人節主題 | 特殊活動 |
| pastel | 粉彩主題 | 柔和風格 |
Fusion 主題配色
Fusion 主題使用 OKLch 色彩空間定義:
/* 主要顏色 */
--p: oklch(50% 0.05 220); /* Primary: 藍灰色 #546E7A */
--s: oklch(55% 0.18 35); /* Secondary: 深橘色 #E64A19 */
--a: oklch(45% 0.15 250); /* Accent: 藍色 #106BA3 */
/* 基礎顏色 */
--b1: oklch(98% 0.01 220); /* base-100: 最淺背景 */
--b2: oklch(94% 0.02 220); /* base-200: 次淺背景 */
--b3: oklch(88% 0.03 220); /* base-300: 邊框/分隔 */
--bc: oklch(25% 0.05 220); /* base-content: 文字 */
/* 語意顏色 */
--in: oklch(70% 0.15 200); /* info: 青色 */
--su: oklch(65% 0.15 165); /* success: 青綠色 */
--wa: oklch(75% 0.15 70); /* warning: 橘色 */
--er: oklch(60% 0.2 25); /* error: 紅色 */
使用語意化顏色
文字顏色
// ✅ 正確:使用語意化顏色
<p className="text-base-content">主要文字</p>
<p className="text-base-content/60">次要文字</p>
<p className="text-primary">強調文字</p>
<p className="text-error">錯誤訊息</p>
// ❌ 錯誤:硬編碼顏色
<p className="text-gray-900">主要文字</p>
<p className="text-red-500">錯誤訊息</p>
背景顏色
// ✅ 正確
<div className="bg-base-100">主要背景</div>
<div className="bg-base-200">次要背景</div>
<div className="bg-primary text-primary-content">強調區塊</div>
// ❌ 錯誤
<div className="bg-white">主要背景</div>
<div className="bg-gray-100">次要背景</div>
邊框顏色
// ✅ 正確
<div className="border border-base-300">卡片</div>
<input className="border-primary focus:border-primary" />
// ❌ 錯誤
<div className="border border-gray-200">卡片</div>
切換主題
使用 data-theme 屬性
// 在 HTML 根元素設定主題
<html data-theme="fusion">
...
</html>
// 動態切換
function ThemeSwitcher() {
const setTheme = (theme: string) => {
document.documentElement.setAttribute('data-theme', theme);
};
return (
<select onChange={(e) => setTheme(e.target.value)}>
<option value="fusion">Fusion</option>
<option value="light">Light</option>
<option value="dark">Dark</option>
</select>
);
}
持久化主題選擇
import { getCookie, setCookie } from '@appfuse/appfuse-web/utils';
// 讀取已儲存的主題
const savedTheme = getCookie('theme') || 'fusion';
document.documentElement.setAttribute('data-theme', savedTheme);
// 儲存主題選擇
function setTheme(theme: string) {
document.documentElement.setAttribute('data-theme', theme);
setCookie('theme', theme, { maxAge: 365 * 24 * 60 * 60 });
}
自訂主題
在 tailwind.css 定義新主題
@plugin "daisyui" {
themes: fusion, light, dark, my-custom-theme;
}
@plugin "daisyui/theme" {
name: "my-custom-theme";
default: false;
/* 主要顏色 */
--p: oklch(55% 0.2 260); /* Primary */
--pc: oklch(98% 0 0); /* Primary content */
--s: oklch(60% 0.15 30); /* Secondary */
--sc: oklch(98% 0 0); /* Secondary content */
--a: oklch(65% 0.2 150); /* Accent */
--ac: oklch(98% 0 0); /* Accent content */
/* 基礎顏色 */
--b1: oklch(98% 0.01 260); /* Base 100 */
--b2: oklch(94% 0.02 260); /* Base 200 */
--b3: oklch(88% 0.03 260); /* Base 300 */
--bc: oklch(25% 0.05 260); /* Base content */
/* 語意顏色 */
--in: oklch(70% 0.15 220); /* Info */
--su: oklch(65% 0.2 145); /* Success */
--wa: oklch(75% 0.15 85); /* Warning */
--er: oklch(60% 0.25 25); /* Error */
/* 設計參數 */
--rounded-box: 0.5rem;
--rounded-btn: 0.375rem;
--rounded-badge: 1rem;
--animation-btn: 0.25s;
--animation-input: 0.2s;
--btn-focus-scale: 0.95;
--border-btn: 1px;
}
設計規範
圓角
| 元素 | 圓角值 | CSS 變數 |
|---|---|---|
| 卡片/容器 | 0.5rem | --rounded-box |
| 按鈕/輸入框 | 0.375rem | --rounded-btn |
| Badge | 1rem | --rounded-badge |
動畫時間
| 元素 | 時間 | CSS 變數 |
|---|---|---|
| 按鈕 | 0.25s | --animation-btn |
| 輸入框 | 0.2s | --animation-input |
字型策略
優先使用系統字型,確保最佳效能:
font-family:
/* macOS */
-apple-system, BlinkMacSystemFont,
/* Windows */
"Segoe UI",
/* Android */
Roboto,
/* 通用 */
"Helvetica Neue", Arial, sans-serif,
/* 中文 */
"Noto Sans TC",
/* Emoji */
"Apple Color Emoji", "Segoe UI Emoji";
元件樣式覆寫
全域覆寫
在 tailwind.css 的 @layer daisyui 中覆寫:
@layer daisyui {
/* 卡片標題不使用粗體 */
.card-title {
font-weight: normal;
}
/* 表格背景色 */
.table {
--tw-bg-opacity: 1;
background-color: var(--fallback-b1, oklch(var(--b1) / var(--tw-bg-opacity)));
}
/* Checkbox 小圓角 */
.checkbox {
--rounded-btn: 0.25rem;
}
}
元件級覆寫
使用 cn() 工具合併樣式:
import { cn } from '@appfuse/appfuse-web/utils';
function CustomButton({ className, ...props }) {
return (
<button
className={cn(
"btn btn-primary",
"rounded-lg shadow-md", // 覆寫樣式
className
)}
{...props}
/>
);
}
深色模式
自動偵測系統偏好
// 偵測系統深色模式偏好
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
const theme = prefersDark ? 'dark' : 'fusion';
document.documentElement.setAttribute('data-theme', theme);
// 監聽系統偏好變更
window.matchMedia('(prefers-color-scheme: dark)')
.addEventListener('change', (e) => {
const theme = e.matches ? 'dark' : 'fusion';
document.documentElement.setAttribute('data-theme', theme);
});
最佳實踐
- 永遠使用語意化顏色 - 不要硬編碼
gray-500、red-600等 - 測試多主題 - 確保元件在不同主題下都正常顯示
- 保持對比度 - 文字與背景對比度至少 4.5:1(WCAG AA)
- 使用 CSS 變數 - 自訂樣式時優先使用 DaisyUI CSS 變數
延伸閱讀
本文檔說明「如何切換與自訂主題」。如需了解設計規範,請參閱設計指南:
- 色彩系統 — 語意化色彩層級、Content 配對、文字透明度、WCAG 對比度
- 密度系統 — 三級密度規範、組件映射、觸控目標
- 文字排版 — 字型堆疊、文字大小、字重
- 間距系統 — 圓角、邊框寬度
- 層次與深度 — 背景色層級、
--depth變數 - 動態效果 — 動畫時長、轉場慣例