5 Thành Phần Quan Trọng Để Xây Dựng Một Design System Hoàn Chỉnh


Từ Design Tokens đến Governance — hướng dẫn chi tiết từng bước cho người mới bắt đầu để xây dựng một design system hoàn chỉnh, kèm ví dụ thực tế và demo trực quan.

“Tại sao mỗi lần làm screen mới, cả team lại phải hỏi nhau màu primary là màu gì? Nút này padding mấy px? Font size h2 là bao nhiêu?” — Nếu câu hỏi này quen thuộc, thì một Design System tốt chính là thứ bạn đang cần. Bài này sẽ giúp bạn hiểu nó từ gốc rễ.

Trước khi đi vào từng phần, mình muốn nói thẳng một điều: Design System không phải là Sticker Sheet trên Figma, cũng không phải Component Library trên Storybook. Đó chỉ là hai mảnh nhỏ trong một hệ thống rộng hơn nhiều — một hệ thống bao gồm quy tắc, ngôn ngữ chung, và cả văn hóa làm việc của team bạn.

Và đây là điều thú vị: bạn không cần phải có đủ cả 5 phần từ ngày đầu. Nhiều team lớn như Spotify hay Airbnb cũng bắt đầu từ một file Figma đơn giản trước khi build ra hệ thống phức tạp như bây giờ. Điều quan trọng là hiểu mình đang xây cái gì để đi đúng hướng.

5 Thành Phần Quan Trọng Để Xây Dựng Một Design System Hoàn Chỉnh

1
Design Tokens — Bộ từ điển chung của cả team

Hãy hình dung thế này: bạn có 10 người trong team, mỗi người đang dùng màu xanh “chính” khác nhau. Designer dùng #6B4EFF, developer A hardcode #6B4EFF vào CSS, developer B dùng blue, developer C dùng rgb(107, 78, 255). Nghe vô lý nhưng đây là thực tế ở rất nhiều team.

Design Tokens giải quyết chính xác vấn đề này. Thay vì mỗi người dùng một “phương ngữ” khác nhau, tất cả đều tham chiếu về một biến chung: color-primary. Khi cần đổi màu, chỉ cần thay đổi một chỗ — mọi nơi đang dùng biến đó sẽ tự động cập nhật.

Các loại Token phổ biến nhất

🎨
Color Tokens
Bảng màu nguyên thủy + vai trò màu (background, text, border, status…)
Aa
Typography Tokens
Font family, size, weight, line-height, letter-spacing — đồng bộ mọi nơi
Spacing Tokens
Margin, padding theo lưới nhất quán — thường là bội số của 4 hoặc 8px
Border & Radius
Độ bo góc, độ dày đường viền — tạo cảm giác thống nhất cho toàn bộ UI
Shadow & Elevation
Các lớp đổ bóng tạo chiều sâu — phân cấp nội dung trên màn hình
Motion Tokens
Duration, easing curve cho animation — thường bị bỏ quên nhưng rất quan trọng

Hai tầng Token: Primitive và Semantic

Đây là điều nhiều người mới hay bỏ qua. Một hệ thống Token tốt thường có hai tầng:

Tầng 1 — Primitive Tokens: Là bảng màu thô, chưa mang ý nghĩa cụ thể. Ví dụ: purple-500gray-100red-600.

Tầng 2 — Semantic Tokens: Là các biến mang ý nghĩa ngữ cảnh, tham chiếu về Primitive Token. Ví dụ: color-primary trỏ về purple-500color-danger trỏ về red-600.

/* Tầng 1: Primitive */ 
--purple-500: #7c3aed; 
--red-600: #dc2626; 
--gray-100: #f3f4f6; 

/* Tầng 2: Semantic — tham chiếu về Primitive */ 
--color-primary: var(--purple-500); 
--color-danger: var(--red-600); 
--color-bg-subtle: var(--gray-100);

Lợi ích của việc tách hai tầng: khi cần rebrand hoặc thêm dark mode, bạn chỉ cần thay đổi Semantic Tokens — không cần sửa từng component một.

Ví dụ: Bảng màu theo vai trò

Purple ramp (50→900)
Token nameGiá trịDùng khi nào
color-bg-primary#ffffffNền trang chính
color-bg-subtle#f5f3ffNền card, section phụ
color-text-primary#111827Tiêu đề, nội dung chính
color-text-secondary#6b7280Mô tả, ghi chú phụ
color-action-primary#7c3aedNút CTA, link, focus ring
color-danger#dc2626Lỗi, cảnh báo xóa
color-success#16a34aThành công, xác nhận

Quy tắc Spacing: Hệ số 8

Phổ biến nhất trong giới design là hệ số 8: 8, 16, 24, 32, 48, 64, 96px. Lý do: hầu hết màn hình và pixel density đều chia hết cho 8, nên layout sẽ luôn sắc nét, không bị mờ do sub-pixel rendering.

Một số team dùng hệ số 4 để có thêm bước nhỏ hơn (4px, 8px, 12px, 16px…). Không có đúng sai — quan trọng là nhất quán trong toàn bộ hệ thống.

Nếu bạn đang dùng Figma, hãy bật Grid 8px ngay từ đầu và đặt Layout Grid cho mọi Frame. Habit nhỏ này sẽ tiết kiệm cho bạn hàng giờ tranh luận với developer về spacing sau này.

Design System nổi tiếng dùng Token như thế nào?

Google
Dynamic Color
Shopify
Semantic Tokens
Uber
Theme Override
Adobe
Multi-platform
Atlassian
Role-based
2
UI Component Library — Hộp LEGO của team bạn

Nếu Design Tokens là nguyên liệu thô, thì Component Library chính là những khối LEGO đã được lắp sẵn. Developer không cần viết lại button từ đầu mỗi lần — chỉ cần kéo từ thư viện ra dùng. Designer không cần vẽ lại modal mỗi khi làm màn hình mới — chỉ cần kéo component vào và điều chỉnh content.

Lợi ích lớn nhất không phải là tiết kiệm thời gian (dù có) — mà là đảm bảo tính nhất quán. Khi tất cả button trong app đều dùng chung một component, thì chỉ cần sửa một chỗ là cả app thay đổi theo.

Triết lý Atomic Design

Cách tổ chức component phổ biến nhất hiện nay là Atomic Design của Brad Frost (2013). Ý tưởng cốt lõi: UI được tạo nên từ những đơn vị nhỏ nhất, kết hợp dần thành phức tạp hơn — giống như nguyên tử tạo nên phân tử, phân tử tạo nên sinh vật.

Atoms — Nguyên tử (nhỏ nhất, không thể chia nhỏ hơn)

Đây là những thành phần HTML cơ bản nhất. Tự chúng không tạo ra chức năng hoàn chỉnh, nhưng là vật liệu để xây mọi thứ khác.

Nhập email…
Nhớ tôi
Mới Hot Beta
Molecules — Phân tử (atoms kết hợp lại)

Khi 2–3 Atoms ghép vào nhau và tạo ra một chức năng cụ thể, ta có Molecule. Chúng là “đơn vị công việc” thực sự — có thể dùng lại ở nhiều ngữ cảnh khác nhau.

Search Bar = Input field + Button tìm kiếm
Tìm kiếm…
Tìm
Breadcrumb = nhiều Link atoms + dấu phân cách
Organisms — Sinh vật (phức tạp, có chức năng hoàn chỉnh)

Organisms là những block UI lớn, bao gồm nhiều Molecules và Atoms. Chúng đủ phức tạp để tự đứng độc lập như một section của trang.

Variant và State: Phần hay bị bỏ sót nhất

Một component không phải chỉ có một trạng thái. Button chẳng hạn — có thể là: Default, Hover, Active, Focus, Disabled, Loading. Nếu không define đủ các state này từ đầu, developer sẽ tự sáng tạo ra cách xử lý riêng — và UI sẽ inconsistent theo cách khó kiểm soát nhất.

States cần có cho ButtonStates cần có cho Input
Default — trạng thái bình thườngDefault — trống, chưa tương tác
Hover — khi di chuột quaFocused — đang nhập liệu
Active / Pressed — đang nhấnFilled — đã có giá trị
Focus — khi dùng keyboard (accessibility!)Error — nhập sai định dạng
Disabled — không thể tương tácSuccess — nhập đúng, đã xác nhận
Loading — đang xử lý requestDisabled — không thể nhập

Sai lầm phổ biến nhất: Build component đẹp nhưng chỉ design một trạng thái. Đến khi developer implement, mỗi state lại có cách xử lý khác nhau vì không có spec rõ ràng. Hậu quả: button disabled trông y chang button active, user không biết cái gì có thể bấm được.

Thứ tự ưu tiên khi mới bắt đầu: Đừng build 50 component cùng lúc. Hãy bắt đầu với 6 component cơ bản nhất: Button, Input, Checkbox/Radio, Dropdown, Modal, và Card. Với 6 thứ này, bạn có thể build được đến 70% màn hình trong hầu hết sản phẩm.

3
Patterns & Templates — Đừng giải cùng một bài toán hai lần

Nếu Components là những khối LEGO riêng lẻ, thì Patterns là những hướng dẫn ghép LEGO để giải một bài toán cụ thể. Sự khác biệt tinh tế nhưng quan trọng: Component là “cái gì” (một button, một input), còn Pattern là “làm thế nào” (cách tổ chức form đăng ký, cách hiển thị notification).

Universal Patterns — Có ở mọi sản phẩm

Form Pattern — Demo

Một Form Pattern tốt định nghĩa cách sắp xếp label, vị trí error message, khi nào validate, cách xử lý required vs optional field.

Empty State Pattern — Demo

Empty State tốt phải giải thích tại sao trống và guide user bước tiếp theo — không để màn hình trống không.

Chưa có dự án nào

Bắt đầu bằng cách tạo dự án đầu tiên của bạn. Chỉ mất vài giây thôi!

Product-specific Patterns — Đặc thù từng sản phẩm

Swipe Left/Right
Quyết định nhanh bằng cử chỉ. Thường gặp ở dating apps (Tinder), email clients (Gmail). Cần define rõ: swipe bao xa thì trigger, animation như thế nào, có undo không.
Infinite Scroll vs Pagination
Hai cách load dữ liệu với UX hoàn toàn khác nhau. Social feed → infinite scroll; kết quả tìm kiếm → pagination vì user cần quay lại trang cụ thể.
Drag to Reorder
Cho phép user sắp xếp thứ tự bằng kéo thả. Phổ biến ở kanban board, playlist, danh sách ưu tiên. Cần visual feedback rõ ràng trong lúc drag.
Progressive Disclosure
Chỉ hiển thị thông tin cần thiết ở bước hiện tại. Giảm cognitive load — hay dùng trong onboarding flow hoặc form nhiều bước.

Cách document một Pattern: Mỗi Pattern cần có ít nhất 4 thứ:

  1. Tên và mô tả ngắn
  2. Khi nào nên dùng,
  3. Khi nào KHÔNG nên dùng,
  4. Ví dụ minh họa.

Phần “khi nào không nên dùng” thường bị bỏ qua nhất — nhưng lại quan trọng nhất để tránh misuse.

4
Content Guidelines — Sản phẩm bạn “nói” như thế nào với user?

Đây là phần thường bị bỏ qua nhất — và khi bị bỏ qua, hậu quả không rõ ràng ngay lập tức, nhưng user cảm nhận được. Bạn có thể có UI đẹp, layout sạch, animation mượt — nhưng nếu một màn hình dùng giọng văn trang trọng “Hệ thống không thể xử lý yêu cầu của Quý khách” trong khi màn hình khác nói “Ôi, có gì đó không ổn rồi!” — trải nghiệm bị đứt gãy cảm xúc.

Voice vs Tone: Hai khái niệm hay bị nhầm

Voice (Giọng nói) là cá tính cố định của sản phẩm — không thay đổi dù ở ngữ cảnh nào. Giống như một người có tính cách nhất định, dù đang vui hay buồn họ vẫn là chính mình.

Tone (Giọng điệu) là cách điều chỉnh giọng nói cho phù hợp với ngữ cảnh. Cùng một brand thân thiện, nhưng khi thông báo lỗi bảo mật thì cần nghiêm túc hơn khi chào mừng user đăng ký.

Không nhất quán
Onboarding: “Chào mừng bạn đến với gia đình chúng mình!”

Lỗi: “Lỗi 403: Truy cập bị từ chối. Vui lòng liên hệ quản trị viên hệ thống.”
Nhất quán
Onboarding: “Chào mừng bạn đến với gia đình chúng mình!”

Lỗi: “Hm, bạn chưa có quyền vào trang này. Thử liên hệ admin nhé?”

Microcopy: Những chữ nhỏ, tác động lớn

Microcopy là những đoạn text ngắn trên giao diện: nhãn button, placeholder trong ô input, thông báo lỗi, tooltip. Chúng thường bị coi là “chỉ cần điền vào cho xong” — nhưng thực ra đây là nơi UX writing tạo ra sự khác biệt lớn nhất.

Button: “Submit” — User không biết submit cái gì, đi đâu, xong rồi sao.
Button: “Gửi đơn đặt hàng” — Rõ ràng action và kết quả sẽ xảy ra.
Lỗi: “Email không hợp lệ” — Vô hồn, không guide được user cần làm gì tiếp theo.
Lỗi: “Email này trông có vẻ chưa đúng — kiểm tra xem có thiếu @ không nhé.” — Thân thiện và hữu ích.
Placeholder: “Nhập tên” — Không cung cấp thêm thông tin gì so với label phía trên.
Placeholder: “Ví dụ: Nguyễn Văn An” — Giúp user hiểu format mong đợi, giảm lỗi nhập liệu.

Grammar & Mechanics: Những quy tắc hay tranh cãi nhất

Viết hoa
Button label: “Đăng ký” hay “ĐĂNG KÝ”? Tiêu đề: sentence case hay title case? Quy định nhất quán để tránh mỗi người làm một kiểu.
Số và đơn vị
Tiền tệ: “100.000đ” hay “100,000 VNĐ” hay “100K”? Ngày tháng: “25/12/2024” hay “25 tháng 12”? Cần nhất quán trong toàn app.
Xưng hô
App gọi user là “bạn”, “anh/chị”, hay “Quý khách”? Ảnh hưởng rất lớn đến tone và cần quyết định từ sớm.
Dấu câu
Tooltip có kết thúc bằng dấu chấm không? Label có dấu hai chấm không? Những thứ nhỏ này tạo nên feel chuyên nghiệp hay amateur.

Mailchimp là ví dụ kinh điển về Content Guidelines làm tốt. Họ define brand voice là “Fun but not silly, Confident but not cocky, Smart but not stodgy” — và mọi copywriter đều viết theo chuẩn đó, tạo ra một giọng văn nhất quán đáng nhớ xuyên suốt toàn bộ sản phẩm và marketing.

5
Documentation & Governance — “Hiến pháp” của Design System

Đây là phần quyết định Design System của bạn sống hay chết về lâu dài. Mình thấy nhiều team build được token đẹp, component xịn, nhưng 6 tháng sau hệ thống trở thành “di tích” — không ai dùng, mỗi team một ngả, component library bị fork 3 lần và không ai biết cái nào là bản chính.

Vấn đề không phải là thiếu thiết kế — mà là thiếu governance. Một Design System không có Documentation rõ ràng giống như một thành phố không có luật: mọi người sẽ tự làm theo cách của mình và tranh cãi mãi về “chuẩn” là gì.

Usage Guidelines — Luật sử dụng

Ví dụ Usage Guideline cho Button Primary
Khi nào dùng: Cho action chính quan trọng nhất trên màn hình. Mỗi screen chỉ có tối đa một Primary Button.

Khi nào KHÔNG dùng: Không dùng cho action hủy hoặc action thứ yếu. Không dùng nhiều hơn một cái trên cùng một màn hình dù có nhiều section.

Lưu ý đặc biệt: Màu đỏ (Destructive variant) chỉ dành cho action xóa vĩnh viễn — không dùng để nhấn mạnh thông tin quan trọng.

Code Snippets — Cầu nối giữa Design và Code

Mỗi component cần có đoạn code tương ứng để developer không phải tự đoán cách implement. Điều này đặc biệt quan trọng với các thuộc tính không nhìn thấy trong design file: animation timing, focus behavior, keyboard navigation.

/* React Component Usage */ 
import {"{ Button }"} from '@acme/design-system'; 
/* Primary action */ 
<Button variant="primary" size="md"> Lưu thay đổi </Button> 
/* Destructive — chỉ dùng cho xóa vĩnh viễn */ 
<Button variant="danger" loading={isDeleting}> Xóa tài khoản </Button> 
/* Disabled state */ 
<Button variant="primary" disabled={!isFormValid}> Tiếp tục </Button>

Governance Process — Quy trình thay đổi

Khi sản phẩm phát triển, sẽ có lúc cần thêm component mới hoặc thay đổi component cũ. Nếu không có quy trình rõ ràng, sẽ xảy ra một trong hai tình huống tệ: hoặc không ai dám thay đổi gì (hệ thống đóng băng), hoặc ai muốn sửa gì thì sửa (hệ thống hỗn loạn).

1. Đề xuất (Proposal)
Ai cũng có thể đề xuất thêm component mới hoặc thay đổi component cũ. Đề xuất cần trả lời: Problem là gì? Solution là gì? Ảnh hưởng đến những chỗ nào đang dùng?
Mở cho tất cả
2. Review (Đánh giá)
Design System team review đề xuất. Kiểm tra: component này có đủ generic để dùng lại không, hay chỉ cần cho một case duy nhất? Có conflict với component nào đang có không?
DS Team review
3. Build & Test
Implement component với đầy đủ states, variants, accessibility. Test trên các breakpoint và với assistive technology. Viết unit test và visual regression test.
Dev + Design cùng làm
4. Document & Release
Viết Usage Guidelines, Code Snippets, ví dụ minh họa. Update changelog. Thông báo cho toàn team. Nếu có breaking change, cần migration guide rõ ràng.
Release với versioning

Ba mô hình Governance phổ biến

Centralized
Một team DS chuyên biệt làm tất cả. Nhất quán cao nhưng có thể trở thành bottleneck khi scale lên nhiều product team.
Federated
Mỗi product team contribute vào DS chung. Scale tốt nhưng cần governance chặt để tránh chaos và inconsistency.

Lời khuyên thực tế: Nếu team bạn dưới 10 người, đừng cần nghĩ đến mô hình phức tạp. Một file Notion với “Ai muốn thêm component mới thì tag @designsystem trên Slack, đợi 2 ngày review” là đủ để bắt đầu. Documentation đơn giản được dùng thực sự còn hơn nhiều documentation hoàn hảo mà không ai đọc.

+
Roadmap thực tế — Bắt đầu từ đâu khi chưa có gì?

Đây là câu hỏi mình được hỏi nhiều nhất. Câu trả lời: đừng cố build cả 5 phần cùng một lúc. Đây là thứ tự ưu tiên mình recommend cho team mới bắt đầu:

Tháng 1: Color & Typography Tokens
Khai báo bảng màu, semantic color tokens, và bộ typography (font, size, weight). Đây là foundation cho mọi thứ sau này. Dùng ngay trong project hiện tại để validate.
Tác động cao, effort thấp
Tháng 2–3: Core Components
Build 6–8 component cơ bản nhất với đầy đủ states và variants: Button, Input, Checkbox, Select, Modal, Card, Badge, Toast notification.
Foundation UI
Tháng 4: Voice & Microcopy Guide
Define brand voice, quy tắc xưng hô, cách viết error message và CTA. Ngắn thôi — 1–2 trang A4 là đủ để bắt đầu và sẽ được mở rộng dần.
Content guidelines v1
Tháng 5–6: Patterns & Documentation
Document những Pattern đang dùng lặp lại nhiều nhất. Thiết lập quy trình đóng góp đơn giản. Bắt đầu có changelog để track thay đổi.
Mở rộng và hoàn thiện

Bạn đang ở đâu trong hành trình này?

Dù bạn đang bắt đầu từ số 0 hay đang muốn cải thiện Design System đang có — hy vọng bài viết này cho bạn một bức tranh rõ ràng hơn về những gì cần xây dựng và theo thứ tự nào.

Bắt đầu với Design Tokens →

Để lại một bình luận

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *