Live Preview
Heading 1
Heading 2
Heading 3
Heading 4
Body text — The quick brown fox jumps over the lazy dog. Lorem ipsum dolor sit amet.
Small text — Used for captions and helper text.
Monospace — code snippets and technical details
Typography System Generation Skill
Skill này hướng dẫn bạn (AI Agent) tạo Typography System — hệ thống chữ hoàn chỉnh bao gồm các semantic text roles ánh xạ đến typography tokens.
1. Mục tiêu (Objective)
Tạo hệ thống Typography với các component/utility class cho mọi vai trò text (display, headline, title, body, label, caption). Đảm bảo nhất quán, accessible, và mapping 100% từ typography tokens.
2. AI Context & Intent (Ngữ cảnh cho AI)
Khi nào dùng Typography?
- MỌI LÚC hiển thị text: heading, paragraph, label, caption
- Đảm bảo nhất quán: Không tự ý chọn font-size/weight — phải dùng typography role
Typography Roles — Hệ thống vai trò chữ
Mỗi role phục vụ một mục đích cụ thể trong hierarchy:
| Role | Mục đích | Khi nào dùng |
|---|---|---|
| Display | Hero text, landing page headline | Rất lớn, branding, 1/page |
| Headline | Section headings | H1–H3, phân chia page sections |
| Title | Component titles | Card title, dialog title, list item title |
| Body | Paragraph, long-form content | Nội dung chính, mô tả, article body |
| Label | Form labels, button text, nav items | UI controls text, compact |
| Caption | Supplementary info | Timestamps, footnotes, helper text, metadata |
Decision Tree cho AI
text
Văn bản cần hiển thị?
├─ Xác định LAYER trước (Ground / Card / Surface)
│ ├─ Ground (page-level) → dùng headline + body
│ ├─ Card (component) → dùng title + body-sm
│ └─ Surface (overlay) → dùng title-sm + caption
│
├─ Chọn ROLE theo mục đích:
│ ├─ Hero / landing / branding → Display (xl, lg)
│ ├─ Page section heading → Headline (lg, md, sm)
│ ├─ Component title (card, dialog) → Title (lg, md, sm)
│ ├─ Main content paragraph → Body (lg, md, sm)
│ ├─ UI control label → Label (lg, md, sm)
│ ├─ Secondary / time / footnote → Caption
│ └─ Inline emphasis → Body + bold/italic
│
└─ Kiểm tra 3-AXIS CONTRAST (T16, T17):
├─ Title weight ≥ 600? ✓
├─ Description dùng muted-foreground? ✓
└─ Size gap ≥ 2 step? ✓
3. Ngữ nghĩa & Phân loại (Semantics)
3.1. Typography Scale — Mapping đến Tokens
| Role | Size | Token font.size |
Token font.weight |
Token font.leading |
Token font.tracking |
HTML |
|---|---|---|---|---|---|---|
| Display XL | 9xl (128px) | font.size.9xl |
font.weight.bold |
– | font.tracking.tight |
<h1> |
| Display LG | 7xl (72px) | font.size.7xl |
font.weight.bold |
– | font.tracking.tight |
<h1> |
| Display MD | 5xl (48px) | font.size.5xl |
font.weight.bold |
– | font.tracking.tight |
<h1> |
| Headline LG | 4xl (36px) | font.size.4xl |
font.weight.semibold |
font.leading.10 |
font.tracking.tight |
<h1> |
| Headline MD | 3xl (30px) | font.size.3xl |
font.weight.semibold |
font.leading.9 |
font.tracking.normal |
<h2> |
| Headline SM | 2xl (24px) | font.size.2xl |
font.weight.semibold |
font.leading.8 |
font.tracking.normal |
<h3> |
| Title LG | xl (20px) | font.size.xl |
font.weight.semibold |
font.leading.7 |
font.tracking.normal |
<h4> |
| Title MD | lg (18px) | font.size.lg |
font.weight.semibold |
font.leading.7 |
font.tracking.normal |
<h5> |
| Title SM | base (16px) | font.size.base |
font.weight.semibold |
font.leading.6 |
font.tracking.normal |
<h6> |
| Body LG | lg (18px) | font.size.lg |
font.weight.normal |
font.leading.7 |
font.tracking.normal |
<p> |
| Body MD | base (16px) | font.size.base |
font.weight.normal |
font.leading.6 |
font.tracking.normal |
<p> |
| Body SM | sm (14px) | font.size.sm |
font.weight.normal |
font.leading.5 |
font.tracking.normal |
<p> |
| Label LG | base (16px) | font.size.base |
font.weight.medium |
font.leading.6 |
font.tracking.normal |
<span> |
| Label MD | sm (14px) | font.size.sm |
font.weight.medium |
font.leading.5 |
font.tracking.normal |
<span> / <label> |
| Label SM | xs (12px) | font.size.xs |
font.weight.medium |
font.leading.4 |
font.tracking.wide |
<span> / <label> |
| Caption | xs (12px) | font.size.xs |
font.weight.normal |
font.leading.4 |
font.tracking.normal |
<span> / <small> |
3.2. Color Tokens cho Typography
| Context | Token Path |
|---|---|
| Default text | base.foreground |
| Secondary/muted text | base.muted-foreground |
| Inverse (on dark bg) | base.foreground-inverse |
| Primary accent text | base.primary-muted-foreground |
| Error text | base.destructive-muted-foreground |
| Success text | base.success-muted-foreground |
| Warning text | base.warning-muted-foreground |
| Info text | base.info-muted-foreground |
3.3. Title/Description Pairing Rules (T16, T17, T18)
Source: title-hierarchy-systems.md — MD3 + shadcn research
3-Axis Contrast — Mọi cặp Title/Description PHẢI đạt ít nhất 2/3 trục:
| Axis | Title | Description | Rule ID |
|---|---|---|---|
| Size | Lớn hơn ≥ 2 step | Nhỏ hơn ≥ 2 step | – |
| Weight | semibold (600) trở lên | regular (400) | T16 |
| Color | foreground / card-foreground |
muted-foreground |
T17 |
Elevation × Typography Matrix (T18):
| Elevation | Title Role | Description Role | Label | Ví dụ |
|---|---|---|---|---|
| Ground | headline-lg→headline-sm |
body-lg→body-md |
label-md |
Page header, section |
| Card | title-lg→title-md |
body-md→body-sm |
label-sm |
Card, stat widget |
| Surface | title-md→title-sm |
body-sm→caption |
label-sm |
Dialog, tooltip, toast |
3.4. Component Typography Spec
| Component | Layer | Title | Description | Label | Caption |
|---|---|---|---|---|---|
| Page Header | Ground | headline-md |
body-md muted |
– | – |
| Section Header | Ground | headline-sm |
body-sm muted |
– | – |
| Card | Card | title-md |
body-sm muted |
label-sm |
caption |
| Stat Widget | Card | label-md (name) |
– | headline-sm (value) |
caption (trend) |
| List Item | Card | title-sm |
body-sm muted |
label-sm |
caption |
| Dialog | Surface | title-lg |
body-md muted |
label-md |
– |
| Toast | Surface | title-sm |
body-sm muted |
– | caption |
| App Bar | Ground | title-md |
– | label-sm |
– |
| Sidebar | Ground | title-sm (section) |
– | label-md (nav) |
caption |
| Table | Card | title-sm (header) |
body-sm (cell) |
label-sm |
caption |
| Form Field | Card | – | body-sm (helper) |
label-md |
caption (error) |
3.5. Anti-patterns (Typography)
| ❌ Sai | ✅ Đúng | Rule |
|---|---|---|
Card title dùng headline-lg |
Card title dùng title-md |
T18 |
| Description cùng foreground với Title | Description dùng muted-foreground |
T17 |
| Title weight 400, Desc weight 400 | Title ≥ 600, Desc 400 | T16 |
Dialog title dùng headline-md |
Dialog title dùng title-lg |
T18 |
4. Token Mapping
📦 Atomic Mapping: See
ATOMIC-MAPPING.mdfor complete token spec.
Xem bảng chi tiết mục 3.1 — mỗi typography role ánh xạ trực tiếp đến bộ 4 tokens:
font.size.*→ font-sizefont.weight.*→ font-weightfont.leading.*→ line-heightfont.tracking.*→ letter-spacing
5. Props & API
typescript
interface TextProps {
/** Typography role — quyết định toàn bộ visual */
role?: 'display-xl' | 'display-lg' | 'display-md' |
'headline-lg' | 'headline-md' | 'headline-sm' |
'title-lg' | 'title-md' | 'title-sm' |
'body-lg' | 'body-md' | 'body-sm' |
'label-lg' | 'label-md' | 'label-sm' |
'caption';
/** Render as HTML tag (override default) */
as?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'p' | 'span' | 'label' | 'small' | 'div';
/** Color variant */
color?: 'default' | 'muted' | 'inverse' | 'primary' | 'destructive' | 'success' | 'warning' | 'info';
/** Text alignment */
align?: 'left' | 'center' | 'right';
/** Truncate with ellipsis */
truncate?: boolean;
/** Max lines before truncation */
maxLines?: number;
/** Weight override (trong cùng role) */
weight?: 'normal' | 'medium' | 'semibold' | 'bold';
/** Content */
children: ReactNode;
}
6. Accessibility (a11y)
- Heading hierarchy: Phải tuân thủ H1 → H2 → H3 theo thứ tự, không nhảy level.
- Không dùng heading cho style: Nếu chỉ cần text to, dùng
role="body-lg"+as="p", KHÔNG dùng<h2>. - Contrast ratio: Text trên background phải đạt tối thiểu 4.5:1 (WCAG AA), 3:1 cho large text.
- Line length: Body text nên 45–75 ký tự/dòng (readability).
- Truncation: Nếu truncate, toàn bộ text phải accessible qua
titleattribute hoặc tooltip.
7. Best Practices & Rules
- Semantic HTML: Role ánh xạ đến HTML tag đúng (headline →
<h*>, body →<p>, label →<label>/<span>). - Prop
asoverride: Cho phép tách visual (role) khỏi semantic (HTML tag) — vd:role="headline-md" as="h3". - Không Hardcode: KHÔNG BAO GIỜ viết
font-size: var(--font-size-sm)trực tiếp — phải dùng token. - Responsive: Display/Headline sizes có thể giảm trên mobile via media query.
- Dark Mode: Tự động qua color tokens.
8. Example Usage
jsx
{/* Page headline */}
<Text role="headline-lg" as="h1">Tổng quan tài khoản</Text>
{/* Card title */}
<Text role="title-md">Giao dịch gần đây</Text>
{/* Body paragraph */}
<Text role="body-md" color="muted">
Tài khoản của bạn đã được kích hoạt thành công.
</Text>
{/* Form label */}
<Text role="label-md" as="label" htmlFor="email">
Email
</Text>
{/* Caption */}
<Text role="caption" color="muted">
Cập nhật lần cuối: 26/02/2026
</Text>
{/* Truncated text */}
<Text role="body-sm" truncate maxLines={2}>
Đây là một đoạn text rất dài sẽ bị cắt sau 2 dòng...
</Text>