Menu
ESC

Nhập từ khóa để tìm kiếm

↑↓ Di chuyển
Enter Mở
ESC Đóng

Đang tải...

Bài 26 — Buttons — Hierarchy & States

Web Design Basics Bài 26/60

Mở đầu — vì sao bài này quan trọng

Hãy thử nhớ lại lần cuối bạn vào một website mua hàng. Cái nút "Mua ngay" hay "Thêm vào giỏ" — bạn có để ý rằng mắt mình tự động bị hút về phía nó không? Đó không phải tình cờ. Đó là kết quả của hàng giờ một designer ngồi tính toán: nút nào nổi bật nhất, nút nào lùi về sau, nút nào trông như đang chờ bạn bấm, nút nào báo cho bạn biết "đợi chút, hệ thống đang xử lý".

Button (nút bấm) nghe có vẻ là thành phần đơn giản nhất trên web — chỉ là một hình chữ nhật có chữ. Nhưng thực tế nó là nơi quyết định chuyện người dùng có hoàn thành hành động hay không. Một website thương mại điện tử có thể có hàng trăm khối nội dung đẹp, nhưng nếu cái nút "Thanh toán" trông mờ nhạt, lẫn vào nền, hoặc không cho biết nó đang phản hồi cú bấm của bạn, thì toàn bộ công sức thiết kế đổ sông đổ biển.

Trong bài này, chúng ta tập trung vào hai trục cốt lõi của button: hierarchy (thứ bậc — nút nào quan trọng hơn nút nào) và states (trạng thái — nút thay đổi ra sao khi người dùng tương tác). Đây là kiến thức nền mà bất kỳ designer web nào cũng phải nắm chắc, vì nó lặp lại trên mọi trang, mọi form, mọi modal bạn từng thiết kế. Nắm vững button, bạn nắm vững một trong những "điểm chạm" sinh ra chuyển đổi (conversion) trên sản phẩm số.

Khái niệm cốt lõi

Button hierarchy — không phải nút nào cũng bằng nhau

Trên một màn hình, hiếm khi chỉ có một nút. Thường có vài nút cùng xuất hiện, và chúng không thể "hét" cùng độ to. Nếu mọi nút đều nổi bật như nhau, người dùng bị tê liệt — họ không biết hành động chính cần làm là gì. Hierarchy chính là việc bạn cố tình làm một số nút nổi bật và một số nút khiêm tốn lại, để dẫn dắt ánh mắt.

Hệ thống phân cấp button phổ biến gồm ba bậc:

Primary button (nút chính) — đại diện cho hành động quan trọng nhất, hành động bạn muốn người dùng làm trên màn hình này. Ví dụ: "Mua ngay", "Đăng ký", "Thanh toán", "Lưu". Về mặt thị giác, nó là nút đậm nhất: nền được tô màu đầy (filled), dùng màu thương hiệu hoặc màu nổi bật, chữ tương phản cao, thường có độ đậm font cao hơn. Nguyên tắc vàng: mỗi màn hình chỉ nên có một primary button trong một vùng nhìn. Khi có hai primary cạnh nhau, chúng triệt tiêu lẫn nhau.

Secondary button (nút phụ) — đại diện cho hành động thay thế, ít quan trọng hơn nhưng vẫn hợp lệ. Ví dụ: "Xem thêm", "Quay lại", "Hủy". Về thị giác, nó nhường chỗ cho primary: thường là outline (chỉ có viền, nền trong suốt), hoặc nền màu nhạt (tinted). Người dùng vẫn thấy nó rõ ràng, nhưng não bộ hiểu ngay đây không phải lựa chọn được khuyến nghị.

Tertiary button (nút cấp ba) — hành động phụ nhất, ít gây chú ý nhất. Thường được thể hiện dạng text button (chỉ có chữ, không viền không nền, trông gần như một link nhưng vẫn là nút) hoặc ghost button. Dùng cho những hành động như "Bỏ qua", "Tìm hiểu thêm", "Đóng".

Bạn không bắt buộc dùng đủ ba bậc trong mọi màn hình. Nhiều màn hình chỉ cần primary + secondary. Quan trọng là sự tương phản về trọng lượng thị giác giữa các nút phản ánh đúng tương phản về mức độ quan trọng của hành động.

Một nguyên tắc thường bị bỏ quên: nút nguy hiểm (destructive)

Ngoài ba bậc trên, có một loại button đặc biệt: destructive button — nút thực hiện hành động không thể hoàn tác hoặc gây mất mát, như "Xóa tài khoản", "Hủy đơn hàng vĩnh viễn". Loại này thường dùng màu đỏ (hoặc màu cảnh báo của hệ thống) để báo hiệu cho người dùng cần cân nhắc. Lưu ý: màu đỏ không có nghĩa nó là primary — một nút "Xóa" màu đỏ vẫn có thể là hành động phụ trong ngữ cảnh, và nên đặt cạnh một nút "Hủy" để người dùng có đường lui.

Button states — nút phải biết "phản hồi"

Người dùng cần biết nút đang ở trạng thái nào. Một nút không phản hồi khi rê chuột, hoặc bấm vào không thấy gì thay đổi, tạo cảm giác "trang bị đơ" — một trong những nguyên nhân lớn nhất khiến người ta rời bỏ. Mỗi button cần được thiết kế đầy đủ các trạng thái sau:

  • Default (Rest) — trạng thái nghỉ, lúc nút chưa bị tương tác. Đây là hình dạng cơ bản.
  • Hover — khi con trỏ chuột rê lên (chỉ áp dụng cho thiết bị có chuột). Thường nút sẫm màu hơn, sáng hơn, hoặc nhô lên nhẹ (shadow) để báo "tôi có thể bấm được".
  • Focus — khi nút được chọn bằng bàn phím (phím Tab). Trạng thái này CỰC KỲ quan trọng cho accessibility — phải có một vòng viền (focus ring) rõ ràng để người dùng dùng bàn phím biết họ đang ở đâu. Đừng bao giờ xóa focus ring chỉ vì "nó xấu".
  • Active (Pressed) — khoảnh khắc người dùng đang nhấn xuống. Thường nút sẫm hơn nữa hoặc thụt vào (inset shadow) để mô phỏng cảm giác "ấn xuống" vật lý.
  • Disabled — nút bị vô hiệu hóa, chưa thể bấm (ví dụ: chưa điền đủ form). Thường mờ đi (giảm độ tương phản, giảm opacity), con trỏ chuyển thành biểu tượng "cấm". Quan trọng: nút disabled vẫn phải đọc được chữ, đừng làm mờ đến mức biến mất.
  • Loading — sau khi bấm, hệ thống đang xử lý. Thường hiện spinner thay cho chữ, hoặc thêm spinner cạnh chữ, đồng thời khóa nút lại để tránh người dùng bấm hai lần (double-submit) — cực kỳ quan trọng với nút "Thanh toán".
Một button được thiết kế tốt là button mà ở bất kỳ thời điểm nào, người dùng cũng đọc được "tín hiệu" từ nó: bấm được không, đang xảy ra gì.

Kích thước chạm và khả năng bấm

Một nút quá nhỏ là một nút khó bấm, đặc biệt trên điện thoại. Các hướng dẫn (Apple HIG, Material Design) khuyến nghị vùng chạm tối thiểu khoảng 44×44px đến 48×48px. Ngón tay người trung bình rộng khoảng 9–10mm, nên nút nhỏ hơn sẽ gây bấm trượt, gây ức chế. Padding bên trong nút (khoảng trống giữa chữ và viền) cũng cần đủ rộng để nút "thở" và dễ bấm.

Tình huống thực tế

Ví dụ 1 — Trang giỏ hàng của một sàn TMĐT Việt Nam

Hãy tưởng tượng một sàn thương mại điện tử Việt Nam, gọi là "ChợViệt". Trên màn hình giỏ hàng có ba hành động: "Thanh toán", "Tiếp tục mua sắm", và "Xóa sản phẩm".

Phiên bản đầu, đội thiết kế làm cả ba nút đều tô màu cam thương hiệu, kích thước bằng nhau, xếp ngang hàng. Kết quả qua A/B test: tỉ lệ người bấm "Thanh toán" thấp một cách bất ngờ, và số người vô tình bấm "Xóa sản phẩm" cao hơn dự kiến. Lý do? Ba nút "hét" cùng độ to, mắt người dùng không biết đâu là hành động chính, và nút "Xóa" — vốn là hành động nguy hiểm — lại nổi bật ngang với "Thanh toán".

Bản sửa: "Thanh toán" giữ là primary (nền cam đầy, to nhất, đặt ở vị trí dễ thấy nhất). "Tiếp tục mua sắm" hạ xuống secondary (outline cam, nền trắng). "Xóa sản phẩm" trở thành tertiary dạng text button màu xám, nhỏ, đặt cạnh từng sản phẩm chứ không nằm chung hàng với hai nút kia. Sau khi đổi, hành động chính được dẫn dắt rõ ràng, và lượng "xóa nhầm" giảm hẳn.

Bài học: Hierarchy không chỉ làm đẹp — nó trực tiếp định hướng hành vi và giảm lỗi thao tác. Hành động nguy hiểm không bao giờ nên cạnh tranh thị giác với hành động chính.

Ví dụ 2 — Nút "Đặt vé" trên app đặt vé xem phim

Một ứng dụng đặt vé xem phim (kiểu như Galaxy Cinema hay CGV) có nút "Đặt vé" ở cuối màn hình chọn ghế. Ban đầu, khi người dùng bấm "Đặt vé", nút không có trạng thái loading. Do hệ thống thanh toán mất 2–3 giây để phản hồi, nhiều người tưởng app bị đơ và bấm liên tục. Hậu quả: một số giao dịch bị gửi trùng, gây ra tình huống đặt nhầm hai vé cho cùng một ghế, và bộ phận chăm sóc khách hàng phải xử lý hàng loạt khiếu nại.

Đội phát triển bổ sung trạng thái loading: ngay khi bấm, chữ "Đặt vé" được thay bằng một spinner, nút chuyển sang trạng thái bị khóa (không bấm lại được), và chỉ mở lại khi server phản hồi. Ngoài ra, họ thêm trạng thái disabled cho nút khi người dùng chưa chọn đủ ghế — nút mờ đi kèm dòng gợi ý "Vui lòng chọn ít nhất 1 ghế". Sau cập nhật, lỗi đặt trùng gần như biến mất.

Bài học: Trạng thái loading và disabled không phải tiểu tiết trang trí — chúng là cơ chế bảo vệ cả người dùng lẫn hệ thống. Với mọi nút kích hoạt giao dịch hoặc gửi dữ liệu, loading state gần như là bắt buộc.

Ví dụ 3 — Modal xác nhận xóa của một SaaS quản lý nhân sự

Một công ty SaaS làm phần mềm quản lý nhân sự cho doanh nghiệp Đông Nam Á có modal hỏi "Bạn có chắc muốn xóa nhân viên này?". Trong modal có hai nút: "Hủy" và "Xóa".

Phiên bản đầu để nút "Xóa" màu đỏ làm primary đậm bên phải, "Hủy" làm text button nhạt bên trái. Vấn đề: theo thói quen, người dùng hay bấm nhanh nút nổi bật nhất bên phải, dẫn đến nhiều ca xóa nhầm nhân viên. Đội UX nhận ra rằng trong một modal xác nhận hành động nguy hiểm, lựa chọn an toàn nên là cái dễ chọn. Họ đổi lại: "Hủy" thành secondary rõ ràng (có viền, nổi bật vừa đủ), "Xóa" vẫn màu đỏ nhưng không phải là nút duy nhất hút mắt. Đồng thời thêm focus mặc định vào nút "Hủy" khi modal mở (để ai bấm Enter theo phản xạ sẽ chọn an toàn).

Bài học: Trong ngữ cảnh nguy hiểm, hierarchy phải phục vụ sự an toàn của người dùng, không chỉ phục vụ tính thẩm mỹ. Màu đỏ báo hiệu nguy hiểm, nhưng không nên biến hành động nguy hiểm thành lựa chọn dễ bấm nhất.

Hướng dẫn từng bước

Khi thiết kế hệ thống button cho một sản phẩm, hãy làm theo trình tự sau:

  • Liệt kê các hành động trên màn hình. Trước khi vẽ, viết ra mọi hành động người dùng có thể làm: "Lưu", "Hủy", "Xem chi tiết", "Xóa"... Đây là bước tư duy, chưa phải bước thiết kế.
  • Xếp hạng mức độ quan trọng. Với mỗi màn hình, xác định ĐÂU là một hành động chính bạn muốn người dùng làm. Đánh dấu nó là primary. Phần còn lại phân vào secondary và tertiary theo mức độ quan trọng giảm dần.
  • Gán phong cách thị giác theo bậc. Primary: filled, màu nổi bật. Secondary: outline hoặc nền nhạt. Tertiary: text button. Destructive: dùng màu cảnh báo nhưng giữ đúng bậc của nó.
  • Định nghĩa đầy đủ các state cho từng kiểu nút. Với mỗi kiểu (primary, secondary...), vẽ ra cả 6 trạng thái: default, hover, focus, active, disabled, loading. Đừng để trống state nào — nếu thiếu, lập trình viên sẽ tự đoán và kết quả thường không nhất quán.
  • Kiểm tra kích thước chạm. Đảm bảo vùng bấm tối thiểu 44–48px, padding đủ rộng, khoảng cách giữa các nút đủ để không bấm nhầm trên điện thoại.
  • Đặt nhãn (label) rõ ràng, dùng động từ. Nhãn nút nên mô tả hành động: "Lưu thay đổi" tốt hơn "OK", "Gửi đơn" tốt hơn "Submit". Người dùng đọc nhãn để biết bấm vào sẽ xảy ra gì.
  • Đưa vào design system / component. Khi đã chốt, biến mỗi kiểu nút thành một component tái sử dụng (trong Figma là component có variants cho từng state và từng bậc). Việc này đảm bảo tính nhất quán trên toàn sản phẩm và tiết kiệm thời gian về sau.

Lỗi thường gặp & mẹo

Lỗi: Quá nhiều primary button cùng lúc. Khi mọi nút đều đậm và nổi bật, không nút nào còn nổi bật. Mẹo: với mỗi vùng nhìn, ép mình chỉ chọn MỘT primary. Nếu thấy cần hai, hãy tự hỏi cái nào thật sự quan trọng hơn.

Lỗi: Xóa focus ring vì "trông xấu". Đây là lỗi accessibility nghiêm trọng. Người dùng bàn phím và người dùng công nghệ trợ giúp dựa vào focus ring để định vị. Mẹo: thay vì xóa, hãy thiết kế một focus ring đẹp và hợp với thương hiệu (ví dụ vòng viền màu nhạt, bo tròn theo nút).

Lỗi: Quên trạng thái loading cho nút gửi dữ liệu. Dẫn đến double-submit. Mẹo: với mọi nút gọi API hoặc thanh toán, mặc định phải có loading state và khóa nút trong lúc xử lý.

Lỗi: Nút disabled mờ đến mức không đọc được. Người dùng không biết nút đó nói gì, vì sao không bấm được. Mẹo: giữ độ tương phản chữ ở mức tối thiểu đọc được, và nếu có thể, thêm dòng gợi ý vì sao nút bị khóa.

Lỗi: Dùng nhãn mơ hồ như "OK", "Yes", "Submit". Người dùng phải đoán. Mẹo: dùng động từ + đối tượng cụ thể: "Xóa bài viết", "Lưu hồ sơ".

Lỗi: Phân biệt primary/secondary chỉ bằng màu. Người mù màu có thể không thấy khác biệt. Mẹo: kết hợp nhiều tín hiệu — filled vs outline, độ đậm chữ, không chỉ dựa vào sắc màu.

Mẹo nâng cao: Hãy thử nhìn màn hình của bạn ở chế độ "nheo mắt" (squint test) — nhíu mắt lại cho mọi thứ mờ đi. Nếu primary button vẫn là thứ nổi bật nhất khi nhìn mờ, hierarchy của bạn đang đúng. Nếu không phân biệt được nút nào với nút nào, bạn cần tăng tương phản.

Bài tập thực hành

  • Phân tích thực tế: Mở 3 website hoặc app bạn hay dùng (ví dụ Shopee, Tiki, một app ngân hàng). Với mỗi màn hình chính, chụp màn hình và đánh dấu: đâu là primary, secondary, tertiary? Có màn hình nào dùng nhiều primary gây rối không? Viết nhận xét ngắn cho từng cái.
  • Thiết kế bộ button states: Chọn một màu thương hiệu bất kỳ. Vẽ (trên giấy hoặc trong công cụ thiết kế) một primary button với đầy đủ 6 trạng thái: default, hover, focus, active, disabled, loading. Lặp lại cho secondary button.
  • Sửa lỗi hierarchy: Lấy ví dụ giỏ hàng "ChợViệt" trong bài. Hãy tự phác thảo lại bố cục ba nút "Thanh toán" / "Tiếp tục mua sắm" / "Xóa sản phẩm" theo cách bạn cho là tối ưu, và giải thích vì sao bạn chọn bậc đó cho từng nút.
  • Viết nhãn nút: Cho 5 nút mơ hồ sau, viết lại nhãn rõ ràng hơn: "OK", "Submit", "Yes", "Click here", "Go". Ghi rõ ngữ cảnh bạn giả định.

Tóm tắt

Button là thành phần nhỏ nhưng quyết định việc người dùng có hoàn thành hành động hay không. Hai trục cốt lõi cần nắm là hierarchystates.

Về hierarchy: không phải nút nào cũng bằng nhau. Primary (filled, nổi bật, mỗi vùng chỉ một) cho hành động chính; secondary (outline hoặc nền nhạt) cho hành động thay thế; tertiary (text button) cho hành động phụ nhất; và destructive (màu cảnh báo) cho hành động nguy hiểm — nhưng không nên biến nó thành nút dễ bấm nhất. Tương phản thị giác giữa các nút phải phản ánh đúng tương phản về mức độ quan trọng.

Về states: mỗi nút phải biết phản hồi. Thiết kế đầy đủ default, hover, focus (đừng bao giờ xóa focus ring), active, disabled và loading. Loading state đặc biệt quan trọng cho nút gửi dữ liệu để tránh double-submit.

Cuối cùng, đừng quên những điều cơ bản nhưng dễ bỏ qua: kích thước chạm tối thiểu 44–48px, nhãn dùng động từ rõ ràng, và đừng phân biệt nút chỉ bằng màu. Khi nghi ngờ hierarchy có đúng không, hãy dùng squint test. Nắm chắc những nguyên tắc này, bạn đã làm chủ một trong những component được dùng nhiều nhất trên mọi sản phẩm web.