Mở đầu — vì sao bài này quan trọng
Ở bài trước, bạn đã học cách phối màu để tạo cảm xúc và sự hài hòa cho giao diện. Nhưng có một sự thật mà nhiều designer mới vào nghề bỏ qua: một bảng màu đẹp trên màn hình Macbook của bạn chưa chắc đã đọc được trên điện thoại của khách hàng ngoài nắng, trên màn hình văn phòng bị chỉnh sáng quá mức, hay với một người dùng bị suy giảm thị lực.
Tại Việt Nam, theo số liệu của Bộ Y tế, có khoảng 2 triệu người mù và thị lực kém, cộng thêm hàng triệu người mắc các tật khúc xạ, loạn sắc (mù màu). Riêng mù màu đỏ-xanh lá ảnh hưởng đến khoảng 8% nam giới — nghĩa là cứ 12 nam khách hàng vào website của bạn thì có 1 người không phân biệt được màu đỏ và xanh lá như bạn. Nếu nút "Hủy" của bạn màu đỏ và nút "Xác nhận" màu xanh lá mà hình dáng giống hệt nhau, người đó sẽ bấm nhầm.
Color Accessibility (khả năng tiếp cận về màu sắc) không phải là chuyện "làm phúc" cho người khuyết tật. Nó là chuyện thiết kế cho mọi điều kiện thực tế: ánh sáng kém, màn hình rẻ tiền, mắt mỏi cuối ngày, tay run khi đi xe bus. Một thiết kế accessible là một thiết kế tốt cho tất cả mọi người. Và WCAG — bộ tiêu chuẩn quốc tế về khả năng tiếp cận web — cho chúng ta những con số cụ thể để đo lường thay vì "cảm thấy đủ tương phản". Đó chính là nội dung trọng tâm của bài này.
Khái niệm cốt lõi
Contrast Ratio (tỉ lệ tương phản) là gì
Contrast ratio là con số đo độ khác biệt về độ sáng (luminance) giữa hai màu — thường là màu chữ (foreground) và màu nền (background). Nó được biểu diễn dưới dạng tỉ lệ, ví dụ 4.5:1 hoặc 7:1.
Thang đo chạy từ 1:1 đến 21:1:
1:1là hai màu giống hệt nhau về độ sáng — chữ tan biến hoàn toàn vào nền, không đọc được.21:1là cặp tương phản cực đại: chữ đen tuyền (#000000) trên nền trắng tinh (#FFFFFF).
Công thức tính (hiểu để dùng, không cần học thuộc)
WCAG tính contrast ratio bằng công thức:
Contrast Ratio = (L1 + 0.05) / (L2 + 0.05)
Trong đó L1 là relative luminance (độ sáng tương đối) của màu sáng hơn, L2 là của màu tối hơn. Relative luminance được tính từ giá trị RGB sau khi đã hiệu chỉnh gamma, với hệ số trọng số khác nhau cho từng kênh (mắt người nhạy với màu xanh lá nhất, nên kênh G có trọng số cao nhất ~0.72).
Bạn không cần tự tính tay con số này. Mọi công cụ đều làm hộ bạn. Nhưng hiểu nguyên lý giúp bạn đoán trước: muốn tăng tương phản, hãy thay đổi độ sáng (làm chữ tối hơn hoặc nền sáng hơn), chứ đừng chỉ đổi sang một màu "rực rỡ" hơn.
Các ngưỡng chuẩn của WCAG 2.1
WCAG có ba mức tuân thủ: A, AA, AAA. Trong thực tế ngành, AA là chuẩn tối thiểu bắt buộc mà bạn phải đạt, AAA là mức lý tưởng nên hướng tới cho nội dung quan trọng.
Đối với văn bản (text):
| Loại nội dung | Mức AA (tối thiểu) | Mức AAA (nâng cao) |
|---|---|---|
| Text thường (normal text) | 4.5:1 | 7:1 |
| Text lớn (large text) | 3:1 | 4.5:1 |
Đối với thành phần phi văn bản (non-text) — như viền ô input, icon mang ý nghĩa, đường biểu đồ, trạng thái focus — WCAG 2.1 (tiêu chí 1.4.11) yêu cầu tối thiểu 3:1 so với màu xung quanh. Đây là điểm rất hay bị quên: cái viền input màu xám nhạt #DDDDDD trên nền trắng của bạn gần như chắc chắn không đạt ngưỡng này.
Một quy ước vàng: màu không bao giờ được là kênh thông tin duy nhất
Tiêu chí WCAG 1.4.1 (Use of Color) nói rõ: bạn không được dùng màu sắc làm cách duy nhất để truyền đạt thông tin. Với người mù màu, "ô tô đỏ" và "ô tô xanh" trông như nhau. Vì vậy:
- Link trong đoạn văn không chỉ đổi màu mà nên có gạch chân.
- Trường form lỗi không chỉ viền đỏ mà nên có icon cảnh báo + dòng chữ mô tả lỗi.
- Biểu đồ không chỉ phân biệt bằng màu mà nên thêm nhãn, pattern, hoặc kiểu nét.
Tình huống thực tế
Tình huống 1 — Sàn TMĐT và nút "Mua ngay" màu vàng
Một startup thương mại điện tử ở TP.HCM (tạm gọi là "ChợViệt") làm lại trang sản phẩm. Designer chọn nút "Mua ngay" màu vàng thương hiệu #FFD400 với chữ trắng #FFFFFF bên trên — trông rất nổi và "sang" trên màn hình thiết kế.
Khi đo, contrast ratio của trắng trên vàng này chỉ là 1.5:1 — thảm họa, xa ngưỡng 4.5:1. Trong buổi user test, một khách hàng lớn tuổi ở quận Bình Thạnh dùng điện thoại Android giá rẻ ngoài quán cà phê ngoài trời nói thẳng: "Chữ trên nút này mờ quá, cô không thấy gì." Đội ngũ đo lại tỉ lệ chuyển đổi: nút này có CTR thấp hơn 30% so với phiên bản cũ.
Cách sửa: giữ nguyên nền vàng thương hiệu (vì nhận diện), nhưng đổi chữ sang đen đậm #1A1A1A. Contrast ratio nhảy lên 11.6:1 — vượt cả AAA. Nút vẫn nổi bật, vẫn đúng brand, nhưng giờ ai cũng đọc được.
Bài học: chữ trắng trên màu sáng (vàng, cam nhạt, xanh mint) gần như luôn fail. Với nền sáng, hãy dùng chữ tối. Đây là lỗi phổ biến số một.
Tình huống 2 — App ngân hàng và trạng thái giao dịch bằng màu
Một ngân hàng số (giả định "TigerBank") hiển thị lịch sử giao dịch: tiền vào hiển thị xanh lá, tiền ra hiển thị đỏ, chỉ khác nhau ở màu, cùng font và cùng dấu. Một khách hàng nam bị mù màu đỏ-xanh lá (deuteranopia) gọi lên tổng đài phàn nàn rằng anh không phân biệt được khoản nào là thu, khoản nào là chi, dẫn đến hiểu nhầm số dư.
Vấn đề ở đây không chỉ là contrast (cả hai màu đều đủ tương phản với nền trắng), mà là vi phạm tiêu chí 1.4.1: màu là kênh thông tin duy nhất. Đội thiết kế sửa bằng cách thêm dấu rõ ràng: tiền vào hiển thị +2.500.000đ với dấu cộng, tiền ra −500.000đ với dấu trừ, đồng thời căn lề và đặt icon mũi tên lên/xuống. Giờ đây dù không nhìn thấy màu, người dùng vẫn hiểu hoàn toàn.
Bài học: đừng bao giờ để một thông tin quan trọng (đúng/sai, vào/ra, còn hàng/hết hàng) chỉ phụ thuộc vào màu. Luôn có thêm một tín hiệu thứ hai: chữ, icon, hình dạng, hoặc dấu.
Tình huống 3 — Landing page với placeholder và viền input mờ
Một agency thiết kế landing page cho khách hàng bất động sản. Form đăng ký tư vấn có các ô input với viền xám rất nhạt #E5E5E5 trên nền trắng, và placeholder text "Nhập số điện thoại" màu #BBBBBB.
Khi audit bằng công cụ, cả hai đều fail: viền chỉ đạt 1.2:1 (cần 3:1 cho non-text), placeholder đạt 2.1:1 (cần tối thiểu 4.5:1 nếu placeholder mang thông tin người dùng cần đọc). Khách hàng lớn tuổi ở Hà Nội phản hồi rằng họ "không thấy có ô nào để điền". Tỉ lệ điền form thấp bất thường.
Cách sửa: đổi viền sang #767676 (đạt 4.5:1, dư sức vượt ngưỡng non-text 3:1) và placeholder sang #6B6B6B. Quan trọng hơn, đội ngũ thêm label cố định phía trên mỗi ô thay vì chỉ dựa vào placeholder — vì placeholder biến mất khi người dùng bắt đầu gõ, gây mất ngữ cảnh.
Bài học: màu xám nhạt "thẩm mỹ tối giản" là cái bẫy lớn nhất của accessibility. Tối giản không có nghĩa là mờ nhạt đến mức không đọc được.
Hướng dẫn từng bước
Đây là quy trình kiểm tra contrast bạn nên áp dụng cho mọi thiết kế:
Bước 1 — Liệt kê các cặp màu chữ/nền chính. Trước khi đo, hãy lập danh sách: chữ body trên nền trang, chữ tiêu đề, chữ trên nút primary, chữ trên nút secondary, placeholder, viền input, link, text trên ảnh nền. Đây là những điểm bắt buộc phải kiểm.
Bước 2 — Đo bằng công cụ. Dùng một trong các công cụ miễn phí phổ biến:
- WebAIM Contrast Checker (webaim.org) — nhập 2 mã màu, nó báo ngay pass/fail cho AA và AAA, cả normal lẫn large text.
- Figma plugins: "Stark" hoặc "Contrast" — đo trực tiếp ngay trong file thiết kế, rất tiện.
- Chrome DevTools: chọn phần tử text, panel màu sẽ hiện luôn contrast ratio và đường ranh giới pass/fail.
Bước 4 — Nếu fail, điều chỉnh độ sáng trước. Đừng đổi sang màu khác hẳn. Hãy giữ hue, chỉ chỉnh lightness (độ sáng trong hệ HSL): làm chữ tối hơn trên nền sáng, hoặc làm nền tối hơn dưới chữ sáng. Đo lại, lặp đến khi đạt.
Bước 5 — Kiểm tra "use of color". Quét toàn bộ giao diện và tự hỏi: có chỗ nào thông tin chỉ được truyền bằng màu không? Nếu có, thêm tín hiệu thứ hai (icon, chữ, gạch chân, dấu).
Bước 6 — Mô phỏng mù màu. Dùng plugin Stark hoặc tính năng "Vision Deficiencies" trong Chrome DevTools (tab Rendering) để xem giao diện qua mắt người mù màu đỏ-xanh, xanh-vàng. Kiểm tra xem mọi thứ còn phân biệt được không.
Bước 7 — Kiểm tra trên thiết bị thật. Cuối cùng, mở thiết kế trên một điện thoại Android tầm trung, ra chỗ sáng. Nếu vẫn đọc tốt, bạn đã ổn.
Lỗi thường gặp & mẹo
Lỗi: Tin vào mắt mình. "Tôi thấy rõ mà" không phải là tiêu chuẩn. Mắt designer thường khỏe, màn hình xịn, ngồi trong phòng máy lạnh ánh sáng lý tưởng. Luôn đo bằng con số.
Lỗi: Chữ trắng trên màu thương hiệu sáng. Vàng, cam, xanh lime, hồng pastel — chữ trắng trên các màu này hầu như luôn fail. Dùng chữ tối thay thế.
Lỗi: Quên trạng thái hover/disabled. Nút disabled thường bị làm mờ đi, và rất hay rớt xuống dưới ngưỡng. WCAG có ngoại lệ cho phần tử "vô hiệu hóa hoàn toàn", nhưng nếu nút disabled vẫn cần người dùng đọc được nhãn để hiểu tại sao, hãy đảm bảo tương phản hợp lý.
Lỗi: Text đè lên ảnh. Ảnh nền có vùng sáng vùng tối, contrast thay đổi liên tục. Mẹo: thêm một lớp overlay tối bán trong suốt (ví dụ đen 40-50% opacity) phủ lên ảnh trước khi đặt chữ trắng. Điều này đảm bảo nền luôn đủ tối ở mọi vùng.
Mẹo: Xây "color token" có ghi sẵn cặp an toàn. Khi làm design system, hãy định nghĩa sẵn từng màu nền đi với màu chữ "on-color" tương ứng đã đạt chuẩn (ví dụ color-primary luôn đi với color-on-primary). Như vậy cả team không phải đo lại mỗi lần dùng.
Mẹo: Đừng nhầm "large text" để biện minh. Một số designer cố hạ chuẩn xuống 3:1 bằng cách gọi mọi thứ là "text lớn". Hãy nhớ định nghĩa chính xác: 18pt thường hoặc 14pt bold. Body text 16px không phải là large text.
Mẹo: AAA cho nội dung đọc lâu. Với bài viết dài, blog, tài liệu — nơi người dùng đọc liên tục nhiều phút — hãy cố đạt AAA (7:1). Mắt sẽ đỡ mỏi hơn nhiều.
Bài tập thực hành
- Audit một website bạn hay dùng. Mở một trang TMĐT Việt Nam (Tiki, Shopee, hoặc trang bất kỳ). Dùng Chrome DevTools chọn 5 phần tử text khác nhau (body, nút, link, placeholder, footer) và ghi lại contrast ratio. Cái nào fail? Đề xuất mã màu thay thế đạt chuẩn.
- Sửa một cặp màu fail. Cho cặp: chữ
#FFFFFFtrên nền#4DA6FF. Đo contrast (gợi ý: khoảng 2.4:1, fail). Hãy điều chỉnh chỉ độ sáng của màu nền trong HSL cho đến khi đạt ít nhất 4.5:1 cho chữ trắng. Ghi lại mã màu mới.
- Thiết kế thông báo trạng thái không phụ thuộc màu. Vẽ (trên giấy hoặc Figma) ba trạng thái: thành công, cảnh báo, lỗi. Yêu cầu: mỗi trạng thái phải phân biệt được kể cả khi in đen trắng. Bạn sẽ dùng icon và chữ gì để bổ sung cho màu?
- Mô phỏng mù màu. Lấy một biểu đồ tròn (pie chart) nhiều màu bất kỳ, bật chế độ mô phỏng deuteranopia trong DevTools. Những lát nào bị trùng nhau? Thiết kế lại bằng cách thêm nhãn hoặc pattern.
Tóm tắt
Color accessibility không phải là tính năng phụ — nó là nền tảng của một thiết kế dùng được cho mọi người, trong mọi điều kiện. Hãy ghi nhớ những con số cốt lõi của WCAG 2.1:
- 4.5:1 — tương phản tối thiểu cho text thường (mức AA).
- 3:1 — tối thiểu cho text lớn (≥18pt thường, hoặc ≥14pt bold) và cho các phần tử phi văn bản như viền, icon, focus state.
- 7:1 — mức AAA lý tưởng cho nội dung đọc lâu.
Một thiết kế đẹp mà 8% nam khách hàng không dùng được thì chưa phải là thiết kế tốt. Khi bạn coi accessibility là một phần của định nghĩa "đẹp", bạn đã nâng tầm mình từ người trang trí giao diện thành một designer thực thụ.