Thời lượng: 1 tuần
Level: Beginner
Yêu cầu: HTML/CSS/JavaScript cơ bản
Tổng quan Module
Module này dạy bạn về Design Tokens - foundation của mọi Design System. Bạn sẽ học tokens là gì, tại sao cần, cách tổ chức, và tooling để manage tokens.
Kết quả học tập
Sau module này, bạn sẽ:
- Hiểu design tokens và lợi ích của chúng
- Thiết kế token taxonomy (phân loại)
- Chọn tooling và format phù hợp
- Implement tokens trong code
Bài 1.1: Tokens là gì và tại sao cần?
Lý thuyết
Design Tokens là gì?
Design tokens là named entities lưu trữ visual design decisions:
/* Hardcoded values */
.button {
background: #3B82F6;
padding: 12px 24px;
border-radius: 8px;
}
/* Design tokens */
.button {
background: var(--color-primary-500);
padding: var(--space-3) var(--space-6);
border-radius: var(--radius-md);
}Lợi ích:
-
Single Source of Truth
- Designer update Figma → tokens update tự động
- Không phải search/replace 100 files
-
Consistency
- Không còn
#3B82F6và#3b82f6vàrgb(59, 130, 246)khác nhau - Mọi nơi dùng
--color-primary-500
- Không còn
-
Theming
- Light/Dark mode chỉ cần swap token values
- Brand colors cho white-label products
-
Multi-platform
- Export tokens → iOS, Android, Web, Flutter
- Same "blue" everywhere
Nguyên tắc then chốt
"Không hardcode values. Mọi visual decision phải thành token."
Nếu bạn viết color: #3B82F6 thay vì color: var(--color-primary), bạn đã fail.
Thực hành
Bài tập: Tìm hardcoded values trong codebase
Checklist:
- Search tất cả hex colors (
#[0-9A-F]{6}) - Search pixel values (
\d+px) - Search font sizes (
font-size: \d+) - List ra 20 values hay dùng nhất
Ví dụ audit:
Found 47 instances of #3B82F6
Found 23 instances of 16px spacing
Found 12 instances of font-size: 14px
Found 8 instances of border-radius: 8px→ Biến chúng thành tokens.
Câu hỏi thảo luận
- Granularity: Every pixel value cần token không? Hay chỉ những values lặp lại?
- Naming:
--blue-500hay--color-primary-500hay--color-brand-primary? - Migration: Codebase 100k lines. Migrate thế nào mà không break production?
Bài 1.2: Token Taxonomy (Phân loại Tokens)
Lý thuyết
3 levels của tokens:
1. Primitive Tokens (Raw values)
--gray-50: #F9FAFB;
--gray-100: #F3F4F6;
--gray-900: #111827;
--blue-500: #3B82F6;
--red-500: #EF4444;2. Semantic Tokens (Meaning-based)
--color-primary: var(--blue-500);
--color-danger: var(--red-500);
--color-text-primary: var(--gray-900);
--color-text-secondary: var(--gray-600);3. Component Tokens (Specific usage)
--button-bg-primary: var(--color-primary);
--button-text-primary: white;
--input-border: var(--gray-300);Categories:
- Colors:
--color-* - Spacing:
--space-* - Typography:
--font-size-*,--font-weight-*,--line-height-* - Radius:
--radius-* - Shadows:
--shadow-* - Z-index:
--z-* - Transitions:
--transition-*
Nguyên tắc then chốt
"Components reference semantic tokens, NOT primitive tokens. Semantic tokens reference primitives."
Button không nên dùng --blue-500 trực tiếp. Dùng --color-primary, rồi --color-primary = --blue-500.
Thực hành
Bài tập: Thiết kế token structure cho org
Color Tokens:
/* Primitives */
:root {
/* Grays */
--gray-50: #F9FAFB;
--gray-100: #F3F4F6;
--gray-200: #E5E7EB;
--gray-300: #D1D5DB;
--gray-400: #9CA3AF;
--gray-500: #6B7280;
--gray-600: #4B5563;
--gray-700: #374151;
--gray-800: #1F2937;
--gray-900: #111827;
/* Brand */
--blue-50: #EFF6FF;
--blue-500: #3B82F6;
--blue-900: #1E3A8A;
--red-50: #FEF2F2;
--red-500: #EF4444;
--red-900: #7F1D1D;
}
/* Semantic */
:root {
--color-primary: var(--blue-500);
--color-primary-hover: var(--blue-600);
--color-danger: var(--red-500);
--color-success: var(--green-500);
--color-warning: var(--yellow-500);
--color-text-primary: var(--gray-900);
--color-text-secondary: var(--gray-600);
--color-text-tertiary: var(--gray-500);
--color-bg-primary: white;
--color-bg-secondary: var(--gray-50);
--color-border: var(--gray-300);
}
/* Dark mode - chỉ swap semantic tokens */
[data-theme="dark"] {
--color-text-primary: var(--gray-50);
--color-text-secondary: var(--gray-400);
--color-bg-primary: var(--gray-900);
--color-bg-secondary: var(--gray-800);
--color-border: var(--gray-700);
}
### Demo: Hệ thống màu sắc
Dưới đây là bản xem trước của hệ thống màu sắc. Bạn có thể thay đổi màu Primary để thấy sự thay đổi đồng bộ trên các thành phần UI:
```playground-config
{
"controls": [
{
"name": "primaryColor",
"label": "Màu sắc chính",
"type": "select",
"options": ["#3b82f6", "#10b981", "#f59e0b", "#ef4444", "#8b5cf6"],
"default": "#3b82f6"
},
{
"name": "borderRadius",
"label": "Bo góc",
"type": "range",
"min": 0,
"max": 20,
"step": 2,
"default": 12
}
]
}Spacing Tokens (8px base):
:root {
--space-0: 0;
--space-1: 4px; /* 0.25rem */
--space-2: 8px; /* 0.5rem */
--space-3: 12px; /* 0.75rem */
--space-4: 16px; /* 1rem */
--space-5: 20px; /* 1.25rem */
--space-6: 24px; /* 1.5rem */
--space-8: 32px; /* 2rem */
--space-10: 40px; /* 2.5rem */
--space-12: 48px; /* 3rem */
--space-16: 64px; /* 4rem */
--space-20: 80px; /* 5rem */
}Nhiệm vụ:
- Thiết kế color scale (50-900)
- Thiết kế spacing scale (8px base)
- Define semantic tokens
- Test dark mode bằng cách swap semantic tokens
Câu hỏi thảo luận
- Too many tokens: 200 tokens khó manage hơn 50 tokens. Làm sao balance?
- Component tokens: Có cần
--button-bg-primaryhay--color-primaryđủ? - Naming convention:
--color-text-primaryvs--text-color-primaryvs--primary-text-color?
Bài 1.3: Token Platform & Tooling
Lý thuyết
Token Formats:
- CSS Custom Properties (Web)
:root {
--color-primary: #3B82F6;
}- JSON (Multi-platform)
{
"color": {
"primary": {
"value": "#3B82F6",
"type": "color"
}
}
}- Style Dictionary (Transform)
{
"color": {
"primary": {
"value": "#3B82F6"
}
}
}→ Generates CSS, SCSS, iOS, Android, Flutter
Tooling:
- Figma Tokens Plugin: Sync Figma ↔ JSON
- Style Dictionary: Transform tokens → multiple platforms
- Theo (Salesforce): Similar to Style Dictionary
- Design Tokens Community Group: W3C standard
Nguyên tắc then chốt
"Tokens nên được version control và build như code, không phải manual copy-paste."
Thực hành
Bài tập: Setup Style Dictionary
1. Install:
npm install style-dictionary2. Create tokens.json:
{
"color": {
"primary": { "value": "#3B82F6" },
"text": {
"primary": { "value": "#111827" },
"secondary": { "value": "#6B7280" }
}
},
"spacing": {
"1": { "value": "4px" },
"2": { "value": "8px" },
"4": { "value": "16px" }
}
}3. Create config.json:
{
"source": ["tokens.json"],
"platforms": {
"css": {
"transformGroup": "css",
"buildPath": "dist/",
"files": [{
"destination": "tokens.css",
"format": "css/variables"
}]
},
"scss": {
"transformGroup": "scss",
"buildPath": "dist/",
"files": [{
"destination": "_tokens.scss",
"format": "scss/variables"
}]
}
}
}4. Build:
npx style-dictionary buildOutput (tokens.css):
:root {
--color-primary: #3B82F6;
--color-text-primary: #111827;
--color-text-secondary: #6B7280;
--spacing-1: 4px;
--spacing-2: 8px;
--spacing-4: 16px;
}Nhiệm vụ:
- Setup Style Dictionary
- Define 30+ tokens
- Generate CSS và SCSS
- Integrate vào build process
Câu hỏi thảo luận
- Figma sync: Làm sao sync tokens giữa Figma và code? Manual hay automated?
- Versioning: Tokens có cần semantic versioning không? Breaking changes khi nào?
- Publishing: Publish tokens thành npm package hay git submodule?
Tổng kết Module
Bạn đã học:
- Design tokens là gì và tại sao cần
- Token taxonomy (primitive → semantic → component)
- Tooling để manage và transform tokens
Bước tiếp theo
Module 2 sẽ dạy về Typography & Spacing Systems - thiết lập type scale và spacing scale nhất quán.