Mở đầu — vì sao bài này quan trọng
Hãy tưởng tượng bạn vừa cài một ứng dụng quản lý chi tiêu mới. Bạn đăng nhập, và màn hình đầu tiên hiện ra là... một khoảng trống mênh mông. Không có giao dịch nào, không có biểu đồ nào, chỉ là một vùng xám trắng với dòng chữ "No data". Trong đầu bạn nảy ra câu hỏi: "Ứng dụng bị lỗi à? Hay mình phải làm gì tiếp theo?" Và rồi bạn thoát ra, có thể là mãi mãi.
Đó chính là cái giá của một empty state (trạng thái trống) được thiết kế tệ. Trong nghề product design, có một sự thật mà người mới hay bỏ qua: trạng thái trống không phải là một "trường hợp ngoại lệ hiếm gặp" — nó thường là ấn tượng đầu tiên mà người dùng có với sản phẩm của bạn. Khi một người dùng mới mở app lần đầu, họ chưa có dữ liệu gì cả. Khi họ tìm kiếm một từ khóa lạ, kết quả có thể là con số 0. Khi họ lọc danh sách quá chặt, màn hình lại trống trơn. Những khoảnh khắc này diễn ra liên tục, và cách bạn xử lý chúng quyết định người dùng cảm thấy được dẫn dắt hay bị bỏ rơi.
Một empty state tốt làm được ba việc cùng lúc: nó giải thích vì sao màn hình đang trống, trấn an rằng không có gì sai cả, và hướng dẫn người dùng bước tiếp theo. Đây là nơi thiết kế chuyển từ "đẹp" sang "có ích thật sự". Trong bài này, chúng ta sẽ đi sâu vào nghệ thuật biến những khoảng trống đáng sợ thành những cơ hội dẫn dắt người dùng.
Khái niệm cốt lõi
Empty state là gì?
Empty state là trạng thái của một màn hình hoặc một thành phần giao diện khi nó không có nội dung để hiển thị. Thay vì để màn hình trống trơn một cách vô nghĩa, ta thiết kế một bố cục có chủ đích để giao tiếp với người dùng trong khoảnh khắc đó.
Điểm mấu chốt cần nhớ: trống không có nghĩa là không quan trọng. Một màn hình trống được thiết kế cẩu thả khiến người dùng nghĩ sản phẩm bị hỏng, kém chất lượng, hoặc đơn giản là "không có gì để làm ở đây". Ngược lại, một empty state được chăm chút khiến người dùng cảm thấy được chào đón và biết chính xác phải làm gì.
Bốn loại empty state thường gặp
Không phải mọi empty state đều giống nhau. Việc đầu tiên một designer giỏi làm là phân loại đúng "vì sao màn hình này đang trống", vì mỗi loại cần một thông điệp khác nhau.
1. Trạng thái khởi đầu (First-use / no data yet). Đây là khi người dùng mới hoàn toàn, chưa tạo ra bất kỳ dữ liệu nào. Ví dụ: một người vừa đăng ký app ghi chú và chưa có ghi chú nào. Đây là loại empty state quan trọng nhất vì nó định hình ấn tượng đầu tiên. Mục tiêu ở đây là truyền cảm hứng và hướng dẫn hành động đầu tiên — chứ không phải báo lỗi.
2. Không có kết quả tìm kiếm (Search 0 results). Người dùng gõ một từ khóa và hệ thống không tìm thấy gì khớp. Khác với loại đầu tiên, ở đây dữ liệu có tồn tại trong hệ thống, chỉ là không khớp với truy vấn. Mục tiêu là giúp người dùng điều chỉnh truy vấn: gợi ý kiểm tra chính tả, thử từ khóa khác, hoặc bỏ bớt điều kiện.
3. Bộ lọc trả về danh sách rỗng (Filter empties list). Người dùng áp nhiều bộ lọc đến mức không còn mục nào thỏa mãn. Đây là một biến thể tinh tế: người dùng biết có dữ liệu (họ vừa thấy nó trước khi lọc), nên thông điệp cần tập trung vào việc nới lỏng hoặc xóa bộ lọc, kèm một nút "Xóa tất cả bộ lọc" rõ ràng.
4. Lỗi hoặc mất kết nối (Error / offline). Màn hình trống không phải vì không có dữ liệu, mà vì hệ thống không lấy được dữ liệu — mất mạng, server lỗi, hết quyền truy cập. Đây thực chất là một dạng error state nhưng hiển thị dưới hình thức màn hình trống. Mục tiêu là giải thích vấn đề trung thực và cung cấp nút "Thử lại". Tuyệt đối không được nhầm loại này với loại 1 — nói "Hãy tạo mục đầu tiên của bạn!" khi thực ra server đang sập là một trải nghiệm tệ hại.
Các thành phần cấu tạo một empty state
Một empty state hoàn chỉnh thường gồm các lớp sau, xếp theo thứ tự ưu tiên thị giác:
- Hình minh họa hoặc icon (illustration / icon): Một hình ảnh thân thiện giúp giảm bớt cảm giác "trống rỗng đáng sợ" và tạo điểm neo thị giác. Hình nên gợi đúng ngữ cảnh — ví dụ một chiếc giỏ hàng trống cho màn hình giỏ hàng. Tránh hình quá vui nhộn khi ngữ cảnh là lỗi.
- Tiêu đề ngắn (headline): Một câu nói rõ chuyện gì đang xảy ra, ví dụ "Chưa có giao dịch nào" thay vì "No data".
- Mô tả phụ (supporting text): Một đến hai câu giải thích thêm hoặc trấn an, ví dụ "Khi bạn thêm khoản chi đầu tiên, nó sẽ hiện ở đây."
- Hành động chính (primary action / CTA): Nút dẫn người dùng làm bước tiếp theo, ví dụ "Thêm giao dịch". Đây thường là phần quan trọng nhất, đặc biệt với empty state khởi đầu.
- Hành động phụ (secondary action): Tùy chọn — như "Xem hướng dẫn", "Nhập dữ liệu từ file", hoặc "Khám phá mẫu có sẵn".
Tình huống thực tế
Ví dụ 1: Tiki và empty state giỏ hàng
Hãy nhìn vào sàn thương mại điện tử Tiki. Khi một người dùng mới mở giỏ hàng mà chưa thêm sản phẩm nào, nếu chỉ hiển thị "Giỏ hàng trống" trên nền trắng, đó là một cơ hội bị bỏ lỡ. Cách làm tốt hơn — và là cách nhiều sàn TMĐT lớn áp dụng — là dùng một hình minh họa giỏ hàng dễ thương, dòng chữ "Giỏ hàng của bạn đang trống", một câu phụ "Hãy khám phá hàng ngàn sản phẩm với giá ưu đãi", kèm nút lớn "Tiếp tục mua sắm" dẫn về trang chủ.
Diễn giải: Khác biệt nằm ở chỗ empty state này không để người dùng rơi vào ngõ cụt. Một giỏ hàng trống là điểm có nguy cơ rời bỏ rất cao — người dùng dễ đóng app. Bằng cách biến nó thành cánh cửa dẫn ngược về catalog sản phẩm, designer đã chuyển một khoảnh khắc "không có gì" thành một cú hích quay lại hành trình mua hàng.
Bài học rút ra: Với các sản phẩm thương mại, empty state là điểm chuyển đổi (conversion point), không chỉ là thông báo. Luôn hỏi: "Tại khoảnh khắc trống này, ta muốn người dùng đi đâu tiếp?"
Ví dụ 2: App fintech và sự cố nhầm loại empty state
Một startup fintech giả định ở TP.HCM — gọi là "VíXanh" — ra mắt app quản lý ví điện tử. Trong tuần đầu, đội ngũ nhận được hàng loạt phàn nàn: "App báo tôi chưa có giao dịch nào nhưng tôi vừa chuyển tiền xong!" Khi điều tra, họ phát hiện vấn đề: màn hình lịch sử giao dịch dùng cùng một empty state cho cả hai trường hợp — khi người dùng thật sự chưa có giao dịch, và khi app không kết nối được tới server.
Lúc mạng yếu, API gọi thất bại, app rơi vào nhánh "không có dữ liệu" và hiển thị thông điệp vui vẻ "Chưa có giao dịch nào, hãy thực hiện giao dịch đầu tiên nhé!" — trong khi người dùng đã có hàng chục giao dịch. Kết quả: người dùng hoang mang, tưởng mất tiền, một số gọi hotline trong hoảng loạn.
Diễn giải: Đây là lỗi kinh điển — gộp empty state khởi đầu với error/offline state làm một. Đội VíXanh sau đó tách rõ hai nhánh: nếu API trả về danh sách rỗng hợp lệ → hiển thị empty state khởi đầu; nếu API lỗi hoặc timeout → hiển thị error state với dòng "Không tải được dữ liệu. Kiểm tra kết nối mạng" và nút "Thử lại".
Bài học rút ra: Trước khi thiết kế giao diện, designer phải làm việc với engineer để phân biệt rạch ròi "rỗng" và "lỗi" ở tầng dữ liệu. Một câu chữ sai ngữ cảnh trong fintech có thể gây hoảng loạn thật sự về tiền bạc.
Ví dụ 3: Notion và empty state mang tính giáo dục
Notion — công cụ ghi chú và quản lý nổi tiếng — xử lý empty state cực kỳ thông minh. Khi bạn tạo một trang mới hoàn toàn trống, thay vì để khoảng trắng, Notion hiển thị một dòng gợi ý mờ ngay tại con trỏ: "Nhập '/' để chọn lệnh, hoặc bắt đầu gõ...". Với người dùng mới, các template (mẫu) còn được đặt ngay trên trang trống đầu tiên: "Bắt đầu với một template" kèm các lựa chọn như To-do list, Meeting notes.
Diễn giải: Notion biến empty state thành một bài học sử dụng tại chỗ (onboarding ngay trong ngữ cảnh). Thay vì một tour hướng dẫn dài dòng tách rời, họ dạy người dùng cách dùng sản phẩm ngay tại khoảnh khắc người dùng cần — khi đối mặt trang trắng. Điều này giảm rào cản "tôi không biết bắt đầu từ đâu", vốn là lý do hàng đầu khiến người dùng bỏ các công cụ năng suất.
Bài học rút ra: Empty state khởi đầu là cơ hội vàng để dạy người dùng. Nếu sản phẩm của bạn có đường cong học tập (learning curve), hãy dùng màn hình trống đầu tiên để giảm ma sát thay vì chỉ thông báo "chưa có gì".
Hướng dẫn từng bước
Đây là quy trình bạn có thể áp dụng để thiết kế empty state cho bất kỳ màn hình nào:
Bước 1 — Liệt kê mọi màn hình có thể trống. Đi qua từng màn hình trong sản phẩm và tự hỏi: "Màn hình này có lúc nào trống không?" Danh sách, kết quả tìm kiếm, bảng dữ liệu, thông báo, tin nhắn, giỏ hàng, dashboard — tất cả đều có khả năng trống. Lập một bảng kê.
Bước 2 — Phân loại nguyên nhân trống. Với mỗi màn hình, xác định nó thuộc loại nào trong bốn loại: khởi đầu, tìm kiếm 0 kết quả, lọc rỗng, hay lỗi/offline. Một màn hình có thể có nhiều loại — ví dụ danh sách sản phẩm vừa có thể trống vì người dùng mới, vừa có thể trống vì lọc quá chặt. Thiết kế riêng cho từng loại.
Bước 3 — Viết phần chữ trước, vẽ sau. Bắt đầu bằng việc viết tiêu đề và mô tả. Tự hỏi: người dùng đang nghĩ gì lúc này? Họ cần được trấn an hay được thúc đẩy hành động? Viết bằng giọng người thật, tránh thuật ngữ kỹ thuật như "null", "no data", "query returned 0 rows".
Bước 4 — Xác định hành động tiếp theo. Mỗi empty state cần một CTA rõ ràng. Với khởi đầu: nút tạo mục đầu tiên. Với lọc rỗng: nút xóa bộ lọc. Với lỗi: nút thử lại. Đặt câu hỏi "ta muốn người dùng đi đâu?" và đặt nút đó nổi bật.
Bước 5 — Thêm hình minh họa phù hợp ngữ cảnh. Chọn icon hoặc illustration gợi đúng tình huống. Giữ phong cách nhất quán với design system của sản phẩm. Với error state, tránh hình quá vui nhộn để không gây cảm giác coi nhẹ vấn đề.
Bước 6 — Kiểm tra với dữ liệu thật và mạng thật. Đừng chỉ kiểm tra trên Figma. Thử app trong điều kiện mất mạng, server chậm, tài khoản mới tinh. Đây là lúc bạn phát hiện những empty state bị bỏ quên hoặc bị nhầm loại như trường hợp VíXanh.
Lỗi thường gặp & mẹo
Lỗi 1 — Bỏ quên empty state hoàn toàn. Đây là lỗi phổ biến nhất. Designer chỉ thiết kế màn hình ở trạng thái "đầy dữ liệu đẹp đẽ" và quên rằng người dùng mới sẽ thấy nó trống. Mẹo: trong mọi file thiết kế, luôn tạo thêm artboard cho trạng thái trống bên cạnh trạng thái đầy.
Lỗi 2 — Dùng chữ kỹ thuật khô khan. "No data available", "0 results", "Error 404" làm người dùng cảm thấy như đang đọc log của lập trình viên. Mẹo: viết như đang nói chuyện với một người bạn — "Chưa có gì ở đây cả, hãy thêm mục đầu tiên nhé."
Lỗi 3 — Nhầm lẫn giữa rỗng và lỗi. Như đã thấy ở ví dụ VíXanh. Mẹo: ở tầng code, luôn phân biệt ba trạng thái — đang tải (loading), tải xong nhưng rỗng (empty), và tải thất bại (error). Ba trạng thái, ba giao diện khác nhau.
Lỗi 4 — Empty state không có lối thoát. Màn hình trống nhưng không có nút nào để làm gì tiếp khiến người dùng mắc kẹt. Mẹo: mọi empty state phải có ít nhất một hành động khả dĩ.
Lỗi 5 — Lạm dụng sự vui nhộn sai chỗ. Một câu đùa dễ thương ở empty state của tin nhắn thì ổn, nhưng cùng giọng đó ở màn hình "không tải được sao kê ngân hàng" thì vô duyên và gây bực bội. Mẹo: điều chỉnh giọng văn theo mức độ nghiêm trọng của ngữ cảnh.
Mẹo nâng cao — Empty state động theo thời gian. Với người dùng cũ đã từng có dữ liệu rồi xóa hết, hãy hiển thị thông điệp khác với người dùng mới tinh. "Bạn đã hoàn thành tất cả công việc!" cho danh sách to-do trống của người dùng cũ tạo cảm giác thành tựu, thay vì "Hãy thêm công việc đầu tiên" — câu này chỉ hợp với người mới.
Bài tập thực hành
Bài tập 1 — Kiểm kê empty state. Chọn một ứng dụng bạn đang dùng (Shopee, Grab, Zalo, hoặc app công ty bạn). Liệt kê tối thiểu 5 màn hình có thể rơi vào trạng thái trống. Với mỗi màn hình, ghi rõ nó thuộc loại nào trong bốn loại đã học và đánh giá empty state hiện tại tốt hay tệ, vì sao.
Bài tập 2 — Thiết kế lại một empty state tệ. Tìm một empty state thực tế mà bạn thấy làm chưa tốt (chỉ có chữ "No data" chẳng hạn). Mở Figma và thiết kế lại nó với đủ bốn thành phần: hình minh họa, tiêu đề, mô tả, và CTA. Viết phần chữ bằng tiếng Việt tự nhiên.
Bài tập 3 — Phân biệt rỗng và lỗi. Cho màn hình "Lịch sử đơn hàng" của một app giao đồ ăn, hãy thiết kế ba phiên bản giao diện riêng biệt: (a) người dùng mới chưa đặt đơn nào, (b) bộ lọc "Đã hủy" trả về rỗng, (c) mất mạng không tải được. Chú ý thông điệp và CTA của ba phiên bản phải khác nhau.
Tóm tắt
Empty state không phải là chuyện nhỏ hay trường hợp ngoại lệ — nó là một phần cốt lõi của trải nghiệm, thường chính là ấn tượng đầu tiên người dùng có với sản phẩm. Những điểm quan trọng cần nhớ:
- Có bốn loại empty state chính: khởi đầu (chưa có dữ liệu), tìm kiếm 0 kết quả, lọc trả về rỗng, và lỗi/offline. Mỗi loại cần thông điệp và hành động riêng.
- Đừng bao giờ nhầm "rỗng" với "lỗi". Ở tầng code phải phân biệt loading, empty và error — như bài học từ VíXanh, nhầm lẫn này có thể gây hoảng loạn thật sự.
- Một empty state hoàn chỉnh gồm hình minh họa, tiêu đề, mô tả, và quan trọng nhất là một CTA dẫn lối. Người dùng không bao giờ nên cảm thấy mắc kẹt.
- Viết bằng giọng người thật, điều chỉnh theo ngữ cảnh — vui nhộn khi nhẹ nhàng, nghiêm túc khi liên quan đến lỗi hay tiền bạc.
- Empty state khởi đầu là cơ hội vàng để truyền cảm hứng và dạy người dùng cách dùng sản phẩm, như cách Notion biến trang trắng thành bài học tại chỗ.