Prisma

Title / Description Hierarchy — Nghiên cứu từ các hệ thống lớn

Mục đích: Phân tích hệ thống typography hierarchy (Title + Description pairs) từ các design system hàng đầu, tập trung Google MD3shadcn/ui, rút ra nguyên tắc chung, và đề xuất áp dụng vào Prisma Design System.


1. Hai hệ thống trọng tâm

1.1. Material Design 3 (Google) — Hệ thống role-based

MD3 chia typography thành 5 role × 3 size = 15 tokens:

Role Large Medium Small Mục đích
Display 57px / 64 lh 45px / 52 lh 36px / 44 lh Hero text, landing, branding
Headline 32px / 40 lh 28px / 36 lh 24px / 32 lh Page titles, content section headers
Title 22px / 28 lh 16px / 24 lh 14px / 20 lh Component headers, card titles
Body 16px / 24 lh 14px / 20 lh 12px / 16 lh Paragraph content, descriptions
Label 14px / 20 lh 12px / 16 lh 11px / 16 lh Buttons, tabs, tags, captions

Nguyên tắc Title/Description trong MD3:

  • Title và Body luôn đi theo cặp (pair): Title = tên gọi, Body = mô tả chi tiết
  • Title dùng Medium weight (500), Body dùng Regular weight (400) → tạo contrast bằng weight, KHÔNG chỉ bằng size
  • Mỗi cặp Title/Body có 3 mức tương ứng: Large pair cho dialogs, Medium pair cho cards, Small pair cho list items
  • Label là role riêng, KHÔNG trộn với Title — Label cho UI control, Title cho content heading

MD3 cặp Title/Description canonical:

Ngữ cảnh Title token Description token Weight gap Size gap
Dialog Title Large (22px/500) Body Medium (14px/400) 100 8px (3 step)
Card Title Medium (16px/500) Body Medium (14px/400) 100 2px (1 step) + weight
List item Title Small (14px/500) Body Small (12px/400) 100 2px (1 step) + weight
App bar Title Large (22px/400)
Navigation Label Large (14px/500)

Insight: MD3 dùng weight làm axis chính để phân biệt Title vs Description, chỉ cần ít nhất 1 step size gap. Đây là khác biệt lớn so với các DS khác.


1.2. shadcn/ui — Hệ thống utility-first

shadcn KHÔNG ship typography tokens/components mặc định — thay vào đó cung cấp utility class recipes dựa trên Tailwind CSS:

Role Tailwind Classes Effective Size Weight Mục đích
h1 text-4xl font-extrabold tracking-tight 36px (2.25rem) 800 Page title, hero
h2 text-3xl font-semibold tracking-tight 30px (1.875rem) 600 Section heading
h3 text-2xl font-semibold tracking-tight 24px (1.5rem) 600 Subsection heading
h4 text-xl font-semibold tracking-tight 20px (1.25rem) 600 Component heading
p leading-7 16px (1rem) 400 Body paragraph
Lead text-xl text-muted-foreground 20px 400 Subtitle / description dưới heading
Large text-lg font-semibold 18px (1.125rem) 600 Inline emphasis, dialog title
Small text-sm font-medium leading-none 14px (0.875rem) 500 Label, form label
Muted text-sm text-muted-foreground 14px 400 Helper text, description, caption

shadcn Color Token Convention (bg/fg pairs):

text
--background / --foreground          ← Page level (Ground)
--card / --card-foreground           ← Card level
--popover / --popover-foreground     ← Surface/overlay level
--muted / --muted-foreground         ← Description, secondary text
--primary / --primary-foreground     ← Action elements
--secondary / --secondary-foreground ← Secondary actions
--destructive / --destructive-foreground

Nguyên tắc Title/Description trong shadcn:

  1. Heading + Lead = cặp chính thứch1 + Lead (text-xl text-muted-foreground) là pattern phổ biến nhất
  2. Weight gradient rõ ràng: h1=extrabold(800) → h2-h4=semibold(600) → Large=semibold(600) → Small=medium(500) → p/Muted=regular(400)
  3. Color làm axis chính cho description: text-muted-foreground = signal rõ ràng "đây là description"
  4. Không có Label riêng: shadcn dùng Small (text-sm font-medium) cho cả label và compact title
  5. Card pattern: CardTitle dùng text-2xl font-semibold + CardDescription dùng text-sm text-muted-foreground

shadcn cặp Title/Description canonical:

Component Title class Description class Cách tạo contrast
Card text-2xl font-semibold (24px/600) text-sm text-muted-foreground (14px/400) Size + Weight + Color
Dialog text-lg font-semibold (18px/600) text-sm text-muted-foreground (14px/400) Size + Weight + Color
Alert text-sm font-medium (14px/500) text-sm [&_p]:leading-relaxed (14px/400) Weight only
Page text-4xl font-extrabold (36px/800) text-xl text-muted-foreground (20px/400) Size + Weight + Color
Toast text-sm font-semibold (14px/600) text-sm opacity-90 (14px) Weight + Opacity

Insight: shadcn luôn dùng 3 trục (Size + Weight + Color) cho các cặp lớn (Card, Page), nhưng cho phép chỉ 1 trục (Weight) cho compact pairs (Alert, Toast).


2. Hệ thống bổ trợ

2.1. IBM Carbon Design System

Carbon chia thành 2 type sets — Productive (fixed) và Expressive (responsive):

Category Productive (fixed) Expressive (responsive)
Heading 01 14px / 18 lh 14px → 16px
Heading 02 16px / 22 lh 16px → 20px
Heading 03 20px / 26 lh 20px → 28px
Heading 04 28px / 36 lh 28px → 36px
Heading 05 32px / 40 lh 32px → 60px
Body 01 14px / 20 lh 14px / 20 lh
Body 02 16px / 24 lh 16px / 24 lh
Helper text 12px / 16 lh 12px / 16 lh
Label 01 12px / 16 lh 12px / 16 lh

Key takeaway: Productive = app/dashboard UI (fixed sizes), Expressive = marketing (responsive). Carbon tách utility styles (Label, Helper) ra khỏi content hierarchy.

2.2. Atlassian Design System

Atlassian dùng T-shirt sizing (XXL→XXS):

Token Size Weight Mục đích
font.heading.xxlarge 29px 700 Brand, marketing
font.heading.large 22px 700 Page titles
font.heading.medium 17px 700 Section headers, modal titles
font.heading.small 14px 600 Card titles
font.heading.xsmall 12px 600 Compact titles (flags)
font.body.large 17px 400 Long-form reading
font.body (default) 14px 400 Component descriptions
font.body.small 12px 400 Fine print

Key takeaway: Heading + Body cùng tier = cặp, e.g. heading.small (14px/600) + font.body.small (12px/400).

2.3. Ant Design

Ant Design dùng pentatonic scale (10 bậc, 12→56px, base=14px):

  • Font weight: Regular(400) + Medium(500) đủ; Semibold(600) cho bold English
  • Khuyến nghị: 3–5 font sizes per page
  • Title/Description pair: cách nhau ≥ 2 bậc trong scale

3. So sánh MD3 vs shadcn — hai triết lý

Tiêu chí MD3 shadcn
Mô hình Role-based tokens (semantic) Utility-class recipes (flexible)
Số lượng roles 5 roles × 3 sizes = 15 9 recipes (h1-h4, p, Lead, Large, Small, Muted)
Weight range 400–500 (chỉ regular/medium) 400–800 (regular→extrabold)
Color as hierarchy axis Không định nghĩa (để cho theme) Có sẵn: foreground vs muted-foreground
Label Role riêng biệt Gộp chung với "Small"
Min font size 11px (Label Small) 14px (text-sm)
Title/Desc gap strategy Weight-first (100 gap) + size Size-first + Weight + Color (3 axes)
Token architecture Semantic tokens → CSS CSS variables (bg/fg pairs) → Tailwind

Bảng mapping chéo:

Vai trò MD3 token shadcn recipe Prisma role
Page hero Display Large text-4xl font-extrabold display-lg
Page title Headline Large text-3xl font-semibold headline-md
Section title Headline Small text-2xl font-semibold (h3) headline-sm
Component title Title Medium text-lg font-semibold (Large) title-md
Card title Title Medium text-2xl font-semibold (CardTitle) title-md
Body text Body Medium leading-7 (p) body-md
Description Body Medium text-sm text-muted-foreground (Muted) body-sm muted
Subtitle Body Large text-xl text-muted-foreground (Lead) body-lg muted
Form label Label Medium text-sm font-medium (Small) label-md
Caption Label Small text-sm text-muted-foreground caption

4. Quy luật chung rút ra (Cross-System Patterns)

4.1. Title / Description luôn đi theo CẶP

Pattern Title Role Description Role Gap
Hero pair Display / Headline LG Body LG / Lead ≥ 3 bậc
Section pair Headline / h2-h3 Body MD / Muted 2 bậc
Component pair Title MD / Large Body SM / Muted 1–2 bậc
Compact pair Title SM / Small Caption / Muted 1 bậc

4.2. Contrast Strategy — 3 trục

text
┌─────────────────────────────────────────────────────┐
│  CONTRAST AXES                                       │  
│                                                      │
│  1. SIZE ──────── Title lớn hơn Description ≥ 2 step │
│  2. WEIGHT ────── Title: semibold/bold (500-700)     │
│                   Description: regular (400)          │
│  3. COLOR ─────── Title: foreground (high contrast)  │
│                   Description: muted-foreground       │
│                                                      │
│  → MD3: weight-first (min 1 step size + weight gap)  │
│  → shadcn: 3-axis cho large, weight-only cho compact │
│  → Prisma: dùng TỐI THIỂU 2/3 trục tại mọi pair   │
└─────────────────────────────────────────────────────┘

4.3. Depth-Based Title Levels

text
Page Level
┌─────────────────────────────────────────────┐
│ Display / Headline LG    ← Page Title       │
│ Body LG / Lead           ← Page Description │
│                                             │
│ Section Level                               │
│ ┌─────────────────────────────────────────┐ │
│ │ Headline MD / SM    ← Section Title     │ │
│ │ Body MD / Muted     ← Section Desc      │ │
│ │                                         │ │
│ │ Component Level                         │ │
│ │ ┌─────────────────────────────────────┐ │ │
│ │ │ Title MD / SM  ← Component Title   │ │ │
│ │ │ Body SM / Muted ← Component Desc   │ │ │
│ │ │                                    │ │ │
│ │ │ Item Level                         │ │ │
│ │ │ ┌──────────────────────────────┐   │ │ │
│ │ │ │ Label / Small ← Item Title  │   │ │ │
│ │ │ │ Caption / Muted ← Item Desc │   │ │ │
│ │ │ └──────────────────────────────┘   │ │ │
│ │ └─────────────────────────────────────┘ │ │
│ └─────────────────────────────────────────┘ │
└─────────────────────────────────────────────┘

4.4. Quy tắc vàng (Golden Rules)

  1. Rule of 2: Title và Description ít nhất cách nhau 2 font-size step (trừ compact pair)
  2. Weight Separation: Title LUÔN nặng hơn Description (≥ 100 gap)
  3. Color Hierarchy: Title = foreground, Description = muted-foreground (giảm 40-50% contrast)
  4. One Display per Page: Chỉ 1 Display style trên toàn trang
  5. 3-5 Scale Rule: MD3 + Ant Design đều khuyến nghị ≤ 5 typography styles trên 1 trang
  6. Productive vs Expressive: App UI → fixed sizes, Landing/Marketing → responsive sizes

5. Áp dụng vào Prisma Design System

5.1. Prisma hiện tại đã có gì?

Prisma đã có hệ thống 6 roles × 3 sizes = 16 variants (hybrid MD3 + shadcn):

text
Display (XL, LG, MD) → 128px, 72px, 48px
Headline (LG, MD, SM) → 36px, 30px, 24px
Title (LG, MD, SM) → 20px, 18px, 16px
Body (LG, MD, SM) → 18px, 16px, 14px
Label (LG, MD, SM) → 16px, 14px, 12px
Caption → 12px

Color tokens (shadcn convention):

text
--foreground / --muted-foreground     ← Ground layer text
--card-foreground                     ← Card layer text
--surface-foreground                  ← Surface layer text (popover equiv)

5.2. Mapping vào 3 Elevation Layers

text
┌──────────────────────────────────────────────────────────────┐
│ GROUND LAYER (page-level content)                            │
│ Background: --background / --canvas                         │
│                                                              │
│ ┌── Page Title ───────────────────────────────────────────┐  │
│ │ Role: headline-lg / headline-md                         │  │
│ │ Weight: semibold (600)                                  │  │
│ │ Color: var(--foreground)                                │  │
│ └─────────────────────────────────────────────────────────┘  │
│ ┌── Page Description ─────────────────────────────────────┐  │
│ │ Role: body-lg / body-md                                 │  │
│ │ Weight: regular (400)                                   │  │
│ │ Color: var(--muted-foreground)                          │  │
│ └─────────────────────────────────────────────────────────┘  │
│                                                              │
│   ┌──────────────────────────────────────────────────────┐   │
│   │ CARD LAYER (component-level)                         │   │
│   │ Background: --card                                   │   │
│   │                                                      │   │
│   │ ┌── Card Title ───────────────────────────────────┐  │   │
│   │ │ Role: title-lg / title-md                       │  │   │
│   │ │ Weight: semibold (600)                          │  │   │
│   │ │ Color: var(--card-foreground)                   │  │   │
│   │ └─────────────────────────────────────────────────┘  │   │
│   │ ┌── Card Description ─────────────────────────────┐  │   │
│   │ │ Role: body-sm / body-md                         │  │   │
│   │ │ Weight: regular (400)                           │  │   │
│   │ │ Color: var(--muted-foreground)                  │  │   │
│   │ └─────────────────────────────────────────────────┘  │   │
│   │                                                      │   │
│   │   ┌──────────────────────────────────────────────┐   │   │
│   │   │ SURFACE LAYER (overlay / elevated)           │   │   │
│   │   │ Background: --surface                        │   │   │
│   │   │                                              │   │   │
│   │   │ ┌── Surface Title ────────────────────────┐  │   │   │
│   │   │ │ Role: title-md / title-sm               │  │   │   │
│   │   │ │ Weight: semibold (600)                  │  │   │   │
│   │   │ │ Color: var(--surface-foreground)        │  │   │   │
│   │   │ └─────────────────────────────────────────┘  │   │   │
│   │   │ ┌── Surface Description ──────────────────┐  │   │   │
│   │   │ │ Role: body-sm / label-md                │  │   │   │
│   │   │ │ Weight: regular (400)                   │  │   │   │
│   │   │ │ Color: var(--muted-foreground)          │  │   │   │
│   │   │ └─────────────────────────────────────────┘  │   │   │
│   │   └──────────────────────────────────────────────┘   │   │
│   └──────────────────────────────────────────────────────┘   │
└──────────────────────────────────────────────────────────────┘

5.3. Elevation × Typography Matrix

Elevation Title Role Description Role Label Role Size Gap Ví dụ
Ground headline-lgheadline-sm body-lgbody-md label-md ≥ 2 bậc Page header, section
Card title-lgtitle-md body-mdbody-sm label-sm ≥ 2 bậc Card, stat widget
Surface title-mdtitle-sm body-smcaption label-sm 1–2 bậc Dialog, tooltip, toast

5.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-md bold body-sm muted label-sm caption
Dialog Surface title-lg body-md muted label-md
Dropdown Item Surface body-sm caption
Toast Surface title-sm body-sm muted caption
Tooltip Surface body-sm
App Bar Ground/Card title-md (page) label-sm (actions)
Sidebar Ground title-sm (section) label-md (nav) caption (badge)
Table Card title-sm (header) body-sm (cell) label-sm (status) caption (meta)
Form Field Card body-sm (helper) label-md (label) caption (error)

5.5. Anti-patterns

❌ Sai ✅ Đúng Lý do
headline-lg cho Card title title-md cho Card title Card ở Card layer, headline cho Ground
Title và Desc cùng size, chỉ khác weight Title ≥ 2 step lớn hơn (trừ compact) Weight alone không đủ trên mobile
6+ font sizes trên 1 page Max 4–5 sizes + variation qua weight/color Quá nhiều gây rối visual
Desc cùng foreground với Title Desc phải dùng muted-foreground Color axis tạo hierarchy
Dialog title dùng headline-md Dialog title dùng title-lg Dialog = Surface layer

References