跳至主要内容

主題系統

AppFuse Web 使用 Tailwind CSS 4 + DaisyUI 5 建構主題系統,支援 30+ 預設主題和自訂主題。

技術架構

預設主題

AppFuse Web 內建 Fusion 主題作為預設,另支援多種 DaisyUI 主題:

主題說明適用場景
fusionAppFuse 品牌主題(預設)企業應用
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
Badge1rem--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);
});

最佳實踐

  1. 永遠使用語意化顏色 - 不要硬編碼 gray-500red-600
  2. 測試多主題 - 確保元件在不同主題下都正常顯示
  3. 保持對比度 - 文字與背景對比度至少 4.5:1(WCAG AA)
  4. 使用 CSS 變數 - 自訂樣式時優先使用 DaisyUI CSS 變數

延伸閱讀

本文檔說明「如何切換與自訂主題」。如需了解設計規範,請參閱設計指南

下一步