Mở đầu — vì sao bài này quan trọng
Nếu bạn nhìn kỹ bất kỳ sản phẩm số nào mình dùng hằng ngày — từ app ngân hàng, sàn thương mại điện tử, cho tới dashboard quản trị nội bộ — bạn sẽ thấy phần lớn diện tích màn hình dành cho một việc: hiển thị dữ liệu. Người dùng mở app ngân hàng để xem lịch sử giao dịch. Mở Shopee để xem danh sách sản phẩm. Mở dashboard bán hàng để xem doanh thu theo ngày. Đằng sau mỗi màn hình đó là một quyết định thiết kế quan trọng mà rất nhiều junior designer bỏ qua: chọn đúng pattern để trình bày dữ liệu.
Sai lầm phổ biến nhất là designer chọn pattern theo cảm tính hoặc theo "đang trend". Thấy card đẹp thì nhét mọi thứ vào card. Thấy bảng cho oai thì dựng bảng 12 cột trên mobile. Kết quả: người dùng phải cuộn ngang khổ sở, không so sánh được thông tin, hoặc quét mãi không tìm thấy con số mình cần.
Table, List và Card không phải ba lựa chọn thẩm mỹ thay thế cho nhau. Chúng là ba công cụ khác nhau cho ba loại nhiệm vụ khác nhau của người dùng. Chọn đúng công cụ, dữ liệu tự nói lên câu chuyện. Chọn sai, dù bạn có tô màu đẹp đến đâu thì trải nghiệm vẫn tệ. Bài này sẽ cho bạn một khung tư duy rõ ràng để không bao giờ phải phân vân "nên dùng cái nào" nữa.
Khái niệm cốt lõi
Bản chất: người dùng đang làm gì với dữ liệu?
Trước khi bàn về hình thức, hãy hỏi: người dùng cần làm gì với dữ liệu này? Có ba nhiệm vụ điển hình:
- So sánh (compare): đặt nhiều mục cạnh nhau và đối chiếu cùng một thuộc tính. Ví dụ: so sánh giá của 5 gói cước, so sánh doanh thu 12 tháng.
- Quét & định vị (scan & locate): lướt qua một danh sách để tìm một mục cụ thể, rồi hành động lên nó. Ví dụ: tìm email chưa đọc, tìm một liên hệ.
- Khám phá & thu hút (browse & engage): duyệt qua các mục giàu hình ảnh, mỗi mục là một "đơn vị nội dung" độc lập hấp dẫn. Ví dụ: duyệt sản phẩm thời trang, duyệt bài viết.
Khi nào dùng cái nào?
| Pattern | Dùng khi | Người dùng quét theo | Ví dụ điển hình |
|---|---|---|---|
| Table (Bảng) | Nhiều cột, cần so sánh đồng cấp, dữ liệu có cấu trúc chặt | Theo cột (column-wise) | Lịch sử giao dịch, báo cáo, admin panel |
| List (Danh sách) | 1–2 thuộc tính chính mỗi mục, cần quét nhanh theo dòng | Theo dòng (row-wise) | Hộp thư, danh bạ, thông báo, feed đơn giản |
| Card (Thẻ) | Nội dung giàu hình ảnh, mỗi mục là một đơn vị độc lập | Theo khối (block-wise) | Sản phẩm e-commerce, bài viết, hồ sơ người dùng |
Table — sức mạnh của việc so sánh theo cột
Bảng mạnh nhất khi người dùng cần so sánh cùng một thuộc tính giữa nhiều mục. Vì các giá trị cùng loại xếp thẳng hàng trong một cột, mắt người quét dọc rất nhanh và phát hiện ngay giá trị bất thường (cao nhất, thấp nhất, âm).
Nguyên tắc thiết kế bảng tốt:
- Căn lề theo loại dữ liệu. Số căn phải (để so sánh độ lớn theo hàng đơn vị), tiền tệ căn phải, text căn trái, ngày tháng căn trái. Đây là lỗi kinh điển: designer căn giữa cột số cho "cân đối" và phá hỏng khả năng so sánh.
- Dùng font tabular (chữ số đều bề rộng). Với cột số, chọn tính năng
tabular-numsđể các chữ số thẳng hàng dọc hoàn hảo. - Hierarchy trong hàng: một hàng nên có một "cột định danh" nổi bật hơn (thường là cột đầu, in đậm), phần còn lại nhẹ hơn.
- Zebra striping hoặc đường kẻ mảnh giúp mắt bám hàng — nhưng đừng lạm dụng cả hai cùng lúc.
- Sticky header khi bảng dài, để người dùng luôn biết mình đang xem cột gì.
- Row actions (sửa, xóa, xem) nên ẩn/mờ và hiện rõ khi hover trên desktop; trên mobile thì gom vào menu ba chấm.
List — tốc độ quét theo dòng
List là "người anh em tối giản" của table. Mỗi item chỉ tập trung 1–2 thông tin chính (primary + secondary), thường kèm một phần tử phụ đầu dòng (avatar, icon, checkbox) và một phần tử phụ cuối dòng (thời gian, badge, mũi tên).
List thắng khi người dùng quét từ trên xuống để tìm một mục rồi hành động. Cấu trúc một dòng — một mục khiến nhịp quét rất nhanh và cực kỳ thân thiện với mobile (mỗi item là một vùng chạm rộng, dễ tap).
Nguyên tắc: giữ mỗi item có một điểm neo thị giác rõ ràng (thường là dòng đầu in đậm), các thông tin phụ nhẹ hơn về màu và weight. Đừng biến list-item thành bảng thu nhỏ với 6 mẩu thông tin ngang hàng.
Card — đơn vị nội dung độc lập, giàu hình ảnh
Card đóng gói một tập thông tin liên quan thành một đơn vị độc lập, có ranh giới rõ ràng (nền, bo góc, shadow nhẹ hoặc viền). Card tỏa sáng khi nội dung có ảnh/thumbnail và mỗi mục xứng đáng được "trưng bày" — như sản phẩm, bài viết, khóa học.
Nguyên tắc: mỗi card nên có một primary action rõ ràng (thường là click cả card), một hình ảnh nhất quán về tỷ lệ khung, và một hệ phân cấp nội dung ổn định (ảnh → tiêu đề → mô tả → giá/CTA). Đừng nhồi quá nhiều hành động vào một card; nó sẽ mất tính "một đơn vị".
Điểm yếu của card: tốn diện tích, khó so sánh chính xác (mắt phải nhảy giữa các khối rời rạc thay vì quét thẳng một cột), và dễ bị "biển card" đơn điệu nếu dùng cho dữ liệu vốn nên là bảng.
Tình huống thực tế
Ví dụ 1 — App ngân hàng: lịch sử giao dịch nên là gì?
Một ngân hàng số Việt Nam (giả định gọi là VBank) làm màn hình lịch sử giao dịch. Bản thiết kế đầu tiên của bạn designer junior dùng card cho mỗi giao dịch: mỗi card có shadow, bo góc 16px, icon danh mục lớn, số tiền to đùng. Nhìn trên artboard rất "premium".
Nhưng khi test với 20 người dùng thật, vấn đề lộ ra: một người dùng bình thường có 40–60 giao dịch/tháng. Với card, mỗi màn hình chỉ hiện được 4–5 giao dịch, người dùng phải cuộn liên tục. Tệ hơn, khi họ muốn kiểm tra "tháng này mình chi bao nhiêu cho ăn uống" — tức là so sánh và tổng hợp các số tiền — thì số tiền nằm rải rác ở vị trí khác nhau trong mỗi card, mắt không quét dọc được.
Team chuyển sang list dày hơn: mỗi dòng gồm icon danh mục nhỏ + tên đơn vị nhận (đậm) + ngày (mờ) bên trái, số tiền căn phải với tabular-nums, tiền ra màu đỏ nhạt, tiền vào màu xanh. Giờ mỗi màn hiện 8–9 giao dịch, cột số tiền thẳng hàng nên người dùng quét dọc rất nhanh để bắt các khoản lớn.
Bài học: dữ liệu đồng dạng, số lượng lớn, người dùng cần quét và đối chiếu con số → list/table thắng card. "Đẹp trên artboard" không đồng nghĩa với "tốt khi có dữ liệu thật".
Ví dụ 2 — Sàn TMĐT: trang danh sách sản phẩm vs. trang so sánh
Một sàn thương mại điện tử Đông Nam Á (kiểu Tiki/Lazada) có hai màn hình dùng chung "dữ liệu sản phẩm" nhưng phục vụ hai nhiệm vụ khác nhau — và họ dùng hai pattern khác nhau, rất đúng.
Ở trang danh mục (browse), nhiệm vụ của người dùng là duyệt và bị thu hút bởi hình ảnh. Ở đây họ dùng card grid: ảnh sản phẩm tỷ lệ 1:1, tên rút gọn 2 dòng, giá đậm, giá gạch, badge "-30%", số sao. Mỗi sản phẩm là một đơn vị độc lập hấp dẫn — đúng lúc để dùng card.
Nhưng khi người dùng bấm "So sánh 3 sản phẩm", họ chuyển sang một bảng so sánh: mỗi sản phẩm là một cột, mỗi thuộc tính (giá, dung lượng, camera, bảo hành) là một hàng. Bây giờ người dùng cần đối chiếu cùng một thuộc tính giữa các sản phẩm, và table là pattern duy nhất làm được điều đó gọn gàng: quét ngang một hàng để thấy ngay sản phẩm nào camera tốt hơn.
Bài học: cùng một dữ liệu, hai nhiệm vụ khác nhau (browse vs. compare) đòi hỏi hai pattern khác nhau. Đừng hỏi "dữ liệu này là gì", hãy hỏi "người dùng đang làm gì với nó".
Ví dụ 3 — Dashboard nội bộ: cái bẫy responsive của bảng
Một startup SaaS làm dashboard quản lý đơn hàng cho nhân viên vận hành. Trên desktop, họ có một bảng 9 cột: mã đơn, khách hàng, sản phẩm, số lượng, giá trị, trạng thái, ngày đặt, ngày giao, hành động. Trên desktop hoàn hảo — nhân viên cần so sánh giá trị đơn, lọc theo trạng thái, sắp xếp theo ngày. Table đúng bài.
Vấn đề đến khi làm bản mobile (nhân viên giao hàng dùng điện thoại). Bản đầu giữ nguyên bảng 9 cột và cho cuộn ngang — một thảm họa: người dùng cuộn qua cuộn lại, luôn mất ngữ cảnh cột nào là cột nào.
Giải pháp: trên mobile, bảng biến hình thành list of cards. Mỗi đơn hàng thành một card: mã đơn + trạng thái (badge màu) ở đầu, tên khách + giá trị nổi bật ở giữa, ngày giao + nút hành động ở cuối. Những cột thứ yếu được gộp hoặc ẩn sau nút "Chi tiết". Đây là kỹ thuật kinh điển gọi là "table trên desktop, card trên mobile".
Bài học: pattern không cố định qua các breakpoint. Bảng dày cột hầu như luôn cần một chiến lược chuyển đổi cho mobile — hoặc thành card, hoặc ẩn cột phụ, chứ đừng bao giờ để người dùng cuộn ngang một bảng 9 cột trên điện thoại.
Hướng dẫn từng bước
Khi đứng trước một màn hình cần hiển thị tập dữ liệu, hãy đi theo quy trình sau:
- Xác định nhiệm vụ chính của người dùng. Họ đang so sánh, quét để tìm, hay duyệt để bị thu hút? Viết nó ra thành một câu. Đây là bước quan trọng nhất — mọi quyết định sau đều dựa vào đây.
- Đếm số thuộc tính "phải thấy" cho mỗi mục. 1–2 thuộc tính → nghiêng về list. 3+ thuộc tính đồng cấp cần đối chiếu → table. Có ảnh và cần trưng bày → card.
- Ước lượng khối lượng dữ liệu thật. Không phải 3 item demo, mà 50–500 item thực tế. Dữ liệu nhiều và đồng dạng → tránh card (tốn diện tích). Bố cục phải sống được với dữ liệu thật.
- Chọn pattern nền tảng dựa trên ba bước trên. Đừng chọn theo thẩm mỹ.
- Thiết kế item mẫu với hệ phân cấp rõ. Mỗi item cần một primary (đậm/lớn), secondary (nhạt), và tối đa vài thông tin phụ. Với table: quyết định căn lề từng cột theo loại dữ liệu.
- Thiết kế các trạng thái đầy đủ. Loading, empty state, error, và trạng thái quá tải (rất nhiều item). (Chi tiết về empty/loading/error sẽ học kỹ ở Bài 26 — ở đây chỉ cần nhớ rằng data display luôn phải có các trạng thái này.)
- Lên chiến lược responsive. Với mỗi breakpoint chính (mobile, tablet, desktop), pattern trông ra sao? Table có biến thành card không? Card grid từ 4 cột xuống 2 cột xuống 1 cột thế nào?
- Thêm tương tác cần thiết: sort, filter, pagination hoặc infinite scroll, row selection. Chỉ thêm cái người dùng thật sự cần cho nhiệm vụ đã xác định ở bước 1.
Lỗi thường gặp & mẹo
- Dùng card cho dữ liệu vốn nên là bảng. Triệu chứng: "biển card" đơn điệu, người dùng phải cuộn nhiều, không so sánh được. Mẹo: nếu bạn thấy mình muốn xếp card thành lưới đều tăm tắp toàn text, gần như chắc chắn bạn cần list hoặc table.
- Căn giữa cột số trong bảng. Phá hỏng khả năng quét dọc. Luôn căn phải số và tiền tệ, căn trái text.
- Bảng nhiều cột cuộn ngang trên mobile. Gần như luôn là trải nghiệm tệ. Chuyển sang card hoặc ẩn cột phụ.
- Item quá tải thông tin. Nhồi 7–8 mẩu dữ liệu ngang hàng vào một list-item khiến không còn điểm neo. Mỗi item cần một primary rõ ràng, phần còn lại lùi về sau.
- Quên empty state và loading. Thiết kế chỉ đẹp khi "có sẵn dữ liệu đầy đủ". Người dùng mới, kết quả lọc rỗng, mạng chậm — tất cả cần được thiết kế.
- Không có hierarchy giữa các cột/thuộc tính. Mọi thứ cùng weight, cùng màu → mắt không biết bám vào đâu. Luôn có một thông tin định danh nổi bật hơn phần còn lại.
- Mẹo mật độ: với công cụ chuyên nghiệp (admin, dashboard), người dùng thường thích mật độ cao (nhiều dòng/màn) để làm việc nhanh. Với sản phẩm hướng người tiêu dùng, mật độ thoáng hơn dễ chịu hơn. Cân nhắc cho phép người dùng chọn chế độ "comfortable / compact".
- Mẹo nhất quán: trong một sản phẩm, hãy chuẩn hóa một vài biến thể list-item và card làm component tái sử dụng, thay vì mỗi màn tự chế một kiểu. Điều này gắn với hệ component bạn xây ở các bài trước.
Bài tập thực hành
Bài 1 — Phân loại nhanh. Với mỗi màn hình sau, chọn pattern (table / list / card) và viết một câu lý do dựa trên nhiệm vụ người dùng: (a) Danh sách khóa học online có thumbnail; (b) Bảng lương nhân viên theo tháng; (c) Danh sách thông báo trong app; (d) Trang so sánh 3 gói bảo hiểm; (e) Feed ảnh du lịch.
Bài 2 — Redesign. Tìm một app ngân hàng hoặc ví điện tử bạn đang dùng, chụp màn hình lịch sử giao dịch. Đánh giá: nó đang dùng pattern gì? Căn lề số có đúng không? Mật độ hợp lý chưa? Vẽ lại một phiên bản list cải tiến trong Figma, chú ý căn phải số tiền và tạo hierarchy rõ giữa tên giao dịch và ngày.
Bài 3 — Responsive. Dựng một bảng đơn hàng 7 cột cho desktop trong Figma, rồi thiết kế phiên bản mobile của nó dưới dạng "list of cards". Ghi rõ cột nào giữ nổi bật, cột nào gộp, cột nào ẩn sau nút chi tiết.
Bài 4 — Card component. Thiết kế một product card có thể tái sử dụng với đầy đủ: ảnh tỷ lệ 1:1, tên 2 dòng, giá, giá gạch, badge giảm giá, rating. Tạo thêm biến thể cho card có ảnh lỗi (fallback) và card đang loading (skeleton).
Tóm tắt
- Table, List, Card không phải ba lựa chọn thẩm mỹ — chúng là ba công cụ cho ba nhiệm vụ khác nhau của người dùng.
- Table: khi cần so sánh nhiều thuộc tính đồng cấp, quét theo cột. Chú ý căn lề theo loại dữ liệu và font tabular.
- List: khi mỗi mục có 1–2 thông tin chính, người dùng quét theo dòng để tìm rồi hành động. Rất thân thiện mobile.
- Card: khi nội dung giàu hình ảnh, mỗi mục là một đơn vị độc lập đáng trưng bày. Tốn diện tích, khó so sánh chính xác.
- Luôn bắt đầu bằng câu hỏi "người dùng đang làm gì với dữ liệu này?", rồi mới chọn hình thức.
- Kiểm nghiệm thiết kế với dữ liệu thật (50–500 item), không phải 3 item demo.
- Pattern không cố định qua breakpoint: bảng dày cột thường cần biến thành card hoặc ẩn cột trên mobile — đừng bao giờ bắt người dùng cuộn ngang.
- Đừng quên các trạng thái loading, empty, error — chúng cũng là một phần của data display.