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
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
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-500, gray-100, red-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-500, color-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ò
| Token name | Giá trị | Dùng khi nào |
|---|---|---|
| color-bg-primary | #ffffff | Nền trang chính |
| color-bg-subtle | #f5f3ff | Nền card, section phụ |
| color-text-primary | #111827 | Tiêu đề, nội dung chính |
| color-text-secondary | #6b7280 | Mô tả, ghi chú phụ |
| color-action-primary | #7c3aed | Nút CTA, link, focus ring |
| color-danger | #dc2626 | Lỗi, cảnh báo xóa |
| color-success | #16a34a | Thà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?
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.
Đâ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.
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.
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 Button | States cần có cho Input |
|---|---|
| Default — trạng thái bình thường | Default — trống, chưa tương tác |
| Hover — khi di chuột qua | Focused — đang nhập liệu |
| Active / Pressed — đang nhấn | Filled — đã có giá trị |
| Focus — khi dùng keyboard (accessibility!) | Error — nhập sai định dạng |
| Disabled — không thể tương tác | Success — nhập đúng, đã xác nhận |
| Loading — đang xử lý request | Disabled — 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.
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
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 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
Cách document một Pattern: Mỗi Pattern cần có ít nhất 4 thứ:
- Tên và mô tả ngắn
- Khi nào nên dùng,
- Khi nào KHÔNG nên dùng,
- 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.
Đâ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ý.
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.”
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.
Grammar & Mechanics: Những quy tắc hay tranh cãi nhất
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.
Đâ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
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).
Ba mô hình Governance phổ biến
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.
Đâ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:
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