606 lines
11 KiB
Markdown
606 lines
11 KiB
Markdown
# DramaLing UI/UX 設計指南
|
||
|
||
## 1. 設計原則
|
||
|
||
### 1.1 核心原則
|
||
- **簡潔直觀**: 介面清晰,操作邏輯簡單
|
||
- **學習優先**: 所有設計服務於學習體驗
|
||
- **響應迅速**: 即時反饋,流暢互動
|
||
- **視覺舒適**: 長時間使用不疲勞
|
||
- **個性化**: 支援自定義偏好
|
||
|
||
### 1.2 設計理念
|
||
```
|
||
學習應該是愉快的體驗
|
||
├── 遊戲化元素激勵學習
|
||
├── 視覺反饋增強記憶
|
||
├── 簡化流程減少負擔
|
||
└── 美觀介面提升動力
|
||
```
|
||
|
||
## 2. 品牌識別
|
||
|
||
### 2.1 品牌色彩
|
||
|
||
```scss
|
||
// 主色調
|
||
$primary-blue: #3B82F6; // 主要操作
|
||
$primary-hover: #2563EB; // 懸停狀態
|
||
$primary-light: #EFF6FF; // 背景色
|
||
|
||
// 輔助色
|
||
$success-green: #10B981; // 成功/正確
|
||
$warning-yellow: #F59E0B; // 警告/提醒
|
||
$error-red: #EF4444; // 錯誤/錯誤答案
|
||
$info-purple: #8B5CF6; // 資訊/提示
|
||
|
||
// 中性色
|
||
$gray-900: #111827; // 主要文字
|
||
$gray-700: #374151; // 次要文字
|
||
$gray-500: #6B7280; // 輔助文字
|
||
$gray-300: #D1D5DB; // 邊框
|
||
$gray-100: #F3F4F6; // 背景
|
||
$gray-50: #F9FAFB; // 淺背景
|
||
|
||
// 深色模式
|
||
$dark-bg: #0F172A; // 深色背景
|
||
$dark-surface: #1E293B; // 深色表面
|
||
$dark-border: #334155; // 深色邊框
|
||
```
|
||
|
||
### 2.2 字體系統
|
||
|
||
```css
|
||
/* 字體家族 */
|
||
--font-sans: 'Inter', 'Noto Sans TC', system-ui, sans-serif;
|
||
--font-mono: 'Fira Code', 'Courier New', monospace;
|
||
|
||
/* 字體大小 */
|
||
--text-xs: 0.75rem; /* 12px - 標籤、註釋 */
|
||
--text-sm: 0.875rem; /* 14px - 輔助文字 */
|
||
--text-base: 1rem; /* 16px - 正文 */
|
||
--text-lg: 1.125rem; /* 18px - 副標題 */
|
||
--text-xl: 1.25rem; /* 20px - 標題 */
|
||
--text-2xl: 1.5rem; /* 24px - 大標題 */
|
||
--text-3xl: 1.875rem; /* 30px - 特大標題 */
|
||
|
||
/* 字重 */
|
||
--font-normal: 400;
|
||
--font-medium: 500;
|
||
--font-semibold: 600;
|
||
--font-bold: 700;
|
||
|
||
/* 行高 */
|
||
--leading-tight: 1.25;
|
||
--leading-normal: 1.5;
|
||
--leading-relaxed: 1.75;
|
||
```
|
||
|
||
### 2.3 間距系統
|
||
|
||
```scss
|
||
// 基礎單位: 4px
|
||
$spacing-1: 0.25rem; // 4px
|
||
$spacing-2: 0.5rem; // 8px
|
||
$spacing-3: 0.75rem; // 12px
|
||
$spacing-4: 1rem; // 16px
|
||
$spacing-5: 1.25rem; // 20px
|
||
$spacing-6: 1.5rem; // 24px
|
||
$spacing-8: 2rem; // 32px
|
||
$spacing-10: 2.5rem; // 40px
|
||
$spacing-12: 3rem; // 48px
|
||
$spacing-16: 4rem; // 64px
|
||
```
|
||
|
||
## 3. 組件設計規範
|
||
|
||
### 3.1 按鈕 (Buttons)
|
||
|
||
#### 樣式變體
|
||
```tsx
|
||
// 主要按鈕 - 重要操作
|
||
<Button variant="primary">開始學習</Button>
|
||
|
||
// 次要按鈕 - 次要操作
|
||
<Button variant="secondary">查看更多</Button>
|
||
|
||
// 輪廓按鈕 - 取消/返回
|
||
<Button variant="outline">取消</Button>
|
||
|
||
// 文字按鈕 - 連結操作
|
||
<Button variant="ghost">跳過</Button>
|
||
|
||
// 危險按鈕 - 刪除操作
|
||
<Button variant="danger">刪除</Button>
|
||
```
|
||
|
||
#### 尺寸規格
|
||
```scss
|
||
// 小型 - 表格操作
|
||
.btn-sm {
|
||
height: 32px;
|
||
padding: 0 12px;
|
||
font-size: 14px;
|
||
}
|
||
|
||
// 中型 - 預設
|
||
.btn-md {
|
||
height: 40px;
|
||
padding: 0 16px;
|
||
font-size: 16px;
|
||
}
|
||
|
||
// 大型 - CTA
|
||
.btn-lg {
|
||
height: 48px;
|
||
padding: 0 24px;
|
||
font-size: 18px;
|
||
}
|
||
```
|
||
|
||
#### 狀態設計
|
||
- **Default**: 正常狀態
|
||
- **Hover**: 滑鼠懸停 - 顏色加深 10%
|
||
- **Active**: 點擊時 - 縮放 95%
|
||
- **Disabled**: 禁用 - 透明度 50%
|
||
- **Loading**: 載入中 - 顯示 spinner
|
||
|
||
### 3.2 卡片 (Cards)
|
||
|
||
#### 詞卡設計
|
||
```html
|
||
<div class="flashcard">
|
||
<!-- 正面 -->
|
||
<div class="flashcard-front">
|
||
<div class="word">negotiate</div>
|
||
<div class="part-of-speech">verb</div>
|
||
<div class="pronunciation">/nɪˈɡoʊʃieɪt/</div>
|
||
</div>
|
||
|
||
<!-- 背面 -->
|
||
<div class="flashcard-back">
|
||
<div class="translation">協商</div>
|
||
<div class="definition">To discuss something...</div>
|
||
<div class="example">
|
||
<p class="en">We need to negotiate a better deal.</p>
|
||
<p class="zh">我們需要協商一個更好的交易。</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
```
|
||
|
||
#### 卡片樣式
|
||
```scss
|
||
.flashcard {
|
||
width: 100%;
|
||
max-width: 400px;
|
||
height: 250px;
|
||
border-radius: 16px;
|
||
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
|
||
background: white;
|
||
padding: 24px;
|
||
transition: transform 0.6s;
|
||
transform-style: preserve-3d;
|
||
|
||
&.flipped {
|
||
transform: rotateY(180deg);
|
||
}
|
||
}
|
||
```
|
||
|
||
### 3.3 表單 (Forms)
|
||
|
||
#### 輸入框設計
|
||
```html
|
||
<div class="form-group">
|
||
<label class="form-label">
|
||
Email
|
||
<span class="required">*</span>
|
||
</label>
|
||
<input
|
||
type="email"
|
||
class="form-input"
|
||
placeholder="Enter your email"
|
||
/>
|
||
<span class="form-error">Please enter a valid email</span>
|
||
</div>
|
||
```
|
||
|
||
#### 表單樣式
|
||
```scss
|
||
.form-input {
|
||
width: 100%;
|
||
height: 44px;
|
||
padding: 0 16px;
|
||
border: 1px solid $gray-300;
|
||
border-radius: 8px;
|
||
font-size: 16px;
|
||
transition: all 0.2s;
|
||
|
||
&:focus {
|
||
outline: none;
|
||
border-color: $primary-blue;
|
||
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
|
||
}
|
||
|
||
&.error {
|
||
border-color: $error-red;
|
||
}
|
||
}
|
||
```
|
||
|
||
### 3.4 導航 (Navigation)
|
||
|
||
#### 頂部導航欄
|
||
```html
|
||
<nav class="navbar">
|
||
<div class="navbar-brand">
|
||
<img src="logo.svg" alt="DramaLing" />
|
||
</div>
|
||
|
||
<div class="navbar-menu">
|
||
<a href="/dashboard" class="nav-link active">儀表板</a>
|
||
<a href="/flashcards" class="nav-link">詞卡</a>
|
||
<a href="/learn" class="nav-link">學習</a>
|
||
<a href="/progress" class="nav-link">進度</a>
|
||
</div>
|
||
|
||
<div class="navbar-actions">
|
||
<button class="icon-btn">
|
||
<BellIcon />
|
||
</button>
|
||
<div class="avatar-menu">
|
||
<img src="avatar.jpg" alt="User" />
|
||
</div>
|
||
</div>
|
||
</nav>
|
||
```
|
||
|
||
#### 手機底部導航
|
||
```html
|
||
<nav class="mobile-nav">
|
||
<a href="/dashboard" class="nav-item active">
|
||
<HomeIcon />
|
||
<span>首頁</span>
|
||
</a>
|
||
<a href="/flashcards" class="nav-item">
|
||
<CardsIcon />
|
||
<span>詞卡</span>
|
||
</a>
|
||
<a href="/learn" class="nav-item">
|
||
<PlayIcon />
|
||
<span>學習</span>
|
||
</a>
|
||
<a href="/profile" class="nav-item">
|
||
<UserIcon />
|
||
<span>我的</span>
|
||
</a>
|
||
</nav>
|
||
```
|
||
|
||
## 4. 響應式設計
|
||
|
||
### 4.1 斷點系統
|
||
|
||
```scss
|
||
// 斷點定義
|
||
$breakpoints: (
|
||
'xs': 0, // <576px - 手機豎屏
|
||
'sm': 576px, // ≥576px - 手機橫屏
|
||
'md': 768px, // ≥768px - 平板豎屏
|
||
'lg': 1024px, // ≥1024px - 平板橫屏/小筆電
|
||
'xl': 1280px, // ≥1280px - 桌面
|
||
'2xl': 1536px // ≥1536px - 大螢幕
|
||
);
|
||
```
|
||
|
||
### 4.2 網格系統
|
||
|
||
```scss
|
||
.container {
|
||
width: 100%;
|
||
margin: 0 auto;
|
||
padding: 0 16px;
|
||
|
||
@media (min-width: 576px) {
|
||
max-width: 540px;
|
||
}
|
||
@media (min-width: 768px) {
|
||
max-width: 720px;
|
||
padding: 0 24px;
|
||
}
|
||
@media (min-width: 1024px) {
|
||
max-width: 960px;
|
||
}
|
||
@media (min-width: 1280px) {
|
||
max-width: 1140px;
|
||
padding: 0 32px;
|
||
}
|
||
}
|
||
```
|
||
|
||
### 4.3 適配策略
|
||
|
||
#### 手機優先
|
||
```scss
|
||
// 基礎樣式 - 手機
|
||
.card {
|
||
padding: 16px;
|
||
font-size: 14px;
|
||
}
|
||
|
||
// 平板增強
|
||
@media (min-width: 768px) {
|
||
.card {
|
||
padding: 24px;
|
||
font-size: 16px;
|
||
}
|
||
}
|
||
|
||
// 桌面優化
|
||
@media (min-width: 1024px) {
|
||
.card {
|
||
padding: 32px;
|
||
}
|
||
}
|
||
```
|
||
|
||
## 5. 動畫與過渡
|
||
|
||
### 5.1 過渡效果
|
||
|
||
```scss
|
||
// 基礎過渡
|
||
.transition-all {
|
||
transition: all 0.2s ease;
|
||
}
|
||
|
||
.transition-colors {
|
||
transition: color 0.2s, background-color 0.2s, border-color 0.2s;
|
||
}
|
||
|
||
.transition-transform {
|
||
transition: transform 0.2s ease;
|
||
}
|
||
|
||
// 緩動函數
|
||
$ease-in: cubic-bezier(0.4, 0, 1, 1);
|
||
$ease-out: cubic-bezier(0, 0, 0.2, 1);
|
||
$ease-in-out: cubic-bezier(0.4, 0, 0.2, 1);
|
||
$bounce: cubic-bezier(0.68, -0.55, 0.265, 1.55);
|
||
```
|
||
|
||
### 5.2 動畫效果
|
||
|
||
```scss
|
||
// 淡入
|
||
@keyframes fadeIn {
|
||
from { opacity: 0; }
|
||
to { opacity: 1; }
|
||
}
|
||
|
||
// 滑入
|
||
@keyframes slideUp {
|
||
from {
|
||
transform: translateY(20px);
|
||
opacity: 0;
|
||
}
|
||
to {
|
||
transform: translateY(0);
|
||
opacity: 1;
|
||
}
|
||
}
|
||
|
||
// 縮放
|
||
@keyframes scaleIn {
|
||
from {
|
||
transform: scale(0.9);
|
||
opacity: 0;
|
||
}
|
||
to {
|
||
transform: scale(1);
|
||
opacity: 1;
|
||
}
|
||
}
|
||
|
||
// 翻轉(詞卡)
|
||
@keyframes flip {
|
||
0% { transform: rotateY(0); }
|
||
100% { transform: rotateY(180deg); }
|
||
}
|
||
```
|
||
|
||
### 5.3 載入動畫
|
||
|
||
```html
|
||
<!-- Spinner -->
|
||
<div class="spinner">
|
||
<div class="spinner-circle"></div>
|
||
</div>
|
||
|
||
<!-- Skeleton -->
|
||
<div class="skeleton">
|
||
<div class="skeleton-line"></div>
|
||
<div class="skeleton-line w-75"></div>
|
||
<div class="skeleton-line w-50"></div>
|
||
</div>
|
||
|
||
<!-- Progress Bar -->
|
||
<div class="progress">
|
||
<div class="progress-bar" style="width: 60%"></div>
|
||
</div>
|
||
```
|
||
|
||
## 6. 圖標系統
|
||
|
||
### 6.1 圖標使用原則
|
||
- 使用 Heroicons 或 Lucide 圖標庫
|
||
- 保持一致的線寬 (2px)
|
||
- 統一尺寸規格 (16px, 20px, 24px)
|
||
- 適當的顏色對比
|
||
|
||
### 6.2 常用圖標
|
||
|
||
```tsx
|
||
// 導航圖標
|
||
<HomeIcon /> // 首頁
|
||
<CardsIcon /> // 詞卡
|
||
<PlayIcon /> // 學習
|
||
<ChartIcon /> // 統計
|
||
<SettingsIcon /> // 設定
|
||
|
||
// 操作圖標
|
||
<PlusIcon /> // 新增
|
||
<EditIcon /> // 編輯
|
||
<TrashIcon /> // 刪除
|
||
<SaveIcon /> // 保存
|
||
<ShareIcon /> // 分享
|
||
|
||
// 狀態圖標
|
||
<CheckIcon /> // 成功
|
||
<XIcon /> // 錯誤
|
||
<InfoIcon /> // 資訊
|
||
<AlertIcon /> // 警告
|
||
<LoadingIcon /> // 載入
|
||
```
|
||
|
||
## 7. 深色模式
|
||
|
||
### 7.1 色彩映射
|
||
|
||
```scss
|
||
// 淺色模式
|
||
:root {
|
||
--bg-primary: #ffffff;
|
||
--bg-secondary: #f9fafb;
|
||
--text-primary: #111827;
|
||
--text-secondary: #6b7280;
|
||
--border: #e5e7eb;
|
||
}
|
||
|
||
// 深色模式
|
||
[data-theme="dark"] {
|
||
--bg-primary: #1e293b;
|
||
--bg-secondary: #0f172a;
|
||
--text-primary: #f9fafb;
|
||
--text-secondary: #94a3b8;
|
||
--border: #334155;
|
||
}
|
||
```
|
||
|
||
### 7.2 切換實現
|
||
|
||
```tsx
|
||
const ThemeToggle = () => {
|
||
const [theme, setTheme] = useState('light');
|
||
|
||
const toggleTheme = () => {
|
||
const newTheme = theme === 'light' ? 'dark' : 'light';
|
||
setTheme(newTheme);
|
||
document.documentElement.setAttribute('data-theme', newTheme);
|
||
};
|
||
|
||
return (
|
||
<button onClick={toggleTheme}>
|
||
{theme === 'light' ? <MoonIcon /> : <SunIcon />}
|
||
</button>
|
||
);
|
||
};
|
||
```
|
||
|
||
## 8. 無障礙設計
|
||
|
||
### 8.1 顏色對比
|
||
- 正常文字: 最低 4.5:1
|
||
- 大文字 (18px+): 最低 3:1
|
||
- 互動元素: 最低 3:1
|
||
- 使用工具檢查對比度
|
||
|
||
### 8.2 鍵盤導航
|
||
```scss
|
||
// 焦點樣式
|
||
:focus-visible {
|
||
outline: 2px solid $primary-blue;
|
||
outline-offset: 2px;
|
||
}
|
||
|
||
// 跳過連結
|
||
.skip-link {
|
||
position: absolute;
|
||
top: -40px;
|
||
left: 0;
|
||
|
||
&:focus {
|
||
top: 0;
|
||
}
|
||
}
|
||
```
|
||
|
||
### 8.3 ARIA 標籤
|
||
```html
|
||
<!-- 按鈕 -->
|
||
<button
|
||
aria-label="Close dialog"
|
||
aria-pressed="false"
|
||
>
|
||
<XIcon aria-hidden="true" />
|
||
</button>
|
||
|
||
<!-- 表單 -->
|
||
<input
|
||
aria-label="Email address"
|
||
aria-required="true"
|
||
aria-invalid="false"
|
||
aria-describedby="email-error"
|
||
/>
|
||
|
||
<!-- 進度 -->
|
||
<div
|
||
role="progressbar"
|
||
aria-valuenow="60"
|
||
aria-valuemin="0"
|
||
aria-valuemax="100"
|
||
>
|
||
60%
|
||
</div>
|
||
```
|
||
|
||
## 9. 效能優化
|
||
|
||
### 9.1 圖片優化
|
||
- 使用 WebP 格式
|
||
- 實施延遲載入
|
||
- 提供多種尺寸
|
||
- 使用 CDN 加速
|
||
|
||
### 9.2 CSS 優化
|
||
- 使用 CSS-in-JS 或 CSS Modules
|
||
- 移除未使用的樣式
|
||
- 最小化 CSS 檔案
|
||
- 使用 PostCSS 自動優化
|
||
|
||
### 9.3 動畫效能
|
||
- 使用 `transform` 和 `opacity`
|
||
- 避免觸發重排
|
||
- 使用 `will-change` 提示
|
||
- 限制同時動畫數量
|
||
|
||
## 10. 設計交付
|
||
|
||
### 10.1 設計檔案
|
||
- Figma 設計稿
|
||
- 組件庫文檔
|
||
- 樣式指南
|
||
- 圖標集合
|
||
|
||
### 10.2 開發資源
|
||
- Design Token (JSON)
|
||
- SVG 圖標檔案
|
||
- 字體檔案
|
||
- 色彩變數
|
||
|
||
### 10.3 規範文檔
|
||
- 組件使用說明
|
||
- 響應式規範
|
||
- 動畫規範
|
||
- 無障礙檢查清單 |