Kiểm tra độ tương phản WCAG AA/AAA | Text trên ảnh hero landing page
Landing SME và agency Việt Nam hay fail WCAG ở đúng chỗ “đẹp nhất”: chữ trên ảnh hero. Mục tiêu thực tế là AA (4.5:1 chữ thường) — không phải AAA mọi nơi. Brand color pastel giữ cho accent; text và CTA chính dùng biến thể đã Pass. Đo bằng số, không bằng mắt trên Figma sáng.
Khi agency bàn giao landing cho cửa hàng, phòng khám hay SaaS nhỏ tại Việt Nam, client thường khen “hero đẹp” rồi vài ngày sau feedback: chữ trên banner khó đọc khi mở ngoài trời. Đó không phải “màn hình điện thoại kém” — thường là độ tương phản (contrast ratio) dưới ngưỡng WCAG 2.1 AA.
Bài này tập trung đúng nỗi đau đó: text trên ảnh, checklist AA vs AAA, và cách đổi brand color vừa đủ để vẫn nhận diện thương hiệu mà không hy sinh khả năng đọc. Dùng kèm công cụ kiểm tra độ tương phản trong trình duyệt.
Ai cần đọc bài này
- Designer / frontend agency làm landing page cho SME
- Freelancer nhận brief “dùng đúng màu brand #… từ logo”
- Dev Nest/Next bàn giao UI và bị client hỏi “sao chữ mờ vậy?”
- QA trước launch campaign Facebook / Zalo Ads dẫn về landing
WCAG 2.1: ngưỡng AA và AAA cần nhớ
WCAG (Web Content Accessibility Guidelines) là chuẩn W3C về khả năng tiếp cận. Phần contrast nằm ở tiêu chí 1.4.3 Contrast (Minimum) (AA) và 1.4.6 Contrast (Enhanced) (AAA).
| Loại nội dung | AA (mục tiêu phổ biến) | AAA (khắt khe hơn) |
|---|---|---|
| Chữ thường (body, mô tả, form label) | ≥ 4.5:1 | ≥ 7:1 |
| Chữ lớn (≥ ~24px hoặc ≥ ~18.66px bold) | ≥ 3:1 | ≥ 4.5:1 |
| UI không phải chữ (viền, icon có nghĩa) | ≥ 3:1 | Không bắt buộc riêng trong 1.4.6 theo cùng cách text |
Công thức (tóm tắt): (L1 + 0.05) / (L2 + 0.05) với L1, L2 là độ chói tương đối (relative luminance). Trắng/đen = 21:1; hai màu giống nhau = 1:1.
Ví dụ số hay gặp:
Chữ #767676 trên nền #FFFFFF → ~4.54:1 → Pass AA chữ thường, Fail AAA
Chữ #FFFFFF trên vùng ảnh sáng #E8E4DC → ~1.3:1 → Fail AA (hero điển hình)
Chữ #FFFFFF trên overlay rgba(0,0,0,0.55) ≈ #737373 nền hiệu dụng → cần đo lại sau khi flatten
Khuyến nghị cho product VN 2026: đặt AA làm cổng QA. AAA dành cho nội dung pháp lý, giáo dục, hoặc khi client có yêu cầu compliance rõ. Ép AAA trên mọi CTA pastel thường làm brand “chết” hoặc chữ thành đen/trắng hoàn toàn.
Vì sao text trên ảnh hero hay fail
1. Đo sai “màu nền”
Designer lấy màu trung bình của ảnh hoặc màu từ logo, rồi đặt chữ trắng. Trên preview Figma zoom nhỏ vẫn “ok”. Trên mobile thật, chữ nằm đúng vùng trời sáng / kính cửa sổ / mặt người → contrast sụp.
Quy tắc: đo contrast trên pixel nền ngay sau chữ, sau khi đã áp overlay CSS, không đo trên bản PSD chưa có lớp tối.
2. Overlay quá mỏng vì sợ “ảnh mất đẹp”
rgba(0,0,0,0.25) trông tinh tế nhưng thường không đủ cho chữ nhỏ 14–16px. Nhiều landing SME dùng headline 28–40px (có thể tính chữ lớn → 3:1) nhưng dòng phụ dưới hero vẫn 16px → vẫn cần 4.5:1.
3. Brand pastel trên nền trắng
Màu brand phổ biến từ identity SME (cam nhạt, xanh mint, hồng):
| Cặp | Ước lượng | AA chữ thường |
|---|---|---|
#F4A261 trên #FFFFFF | ~2.3:1 | Fail |
#2A9D8F trên #FFFFFF | ~3.0:1 | Fail (gần Pass chữ lớn) |
#1B4332 trên #FFFFFF | ~10:1 | Pass AA + AAA |
Agency hay bị brief: “dùng đúng #F4A261 cho mọi chữ CTA”. Kết quả: đẹp trên mock, fail checklist, khách hàng lớn tuổi đọc không nổi.
Brand color vs khả năng đọc — cách tradeoff
Đừng chọn giữa “giữ brand” và “đạt AA” như hai cực. Tách vai trò màu:
- brand.primary — logo, illustration, chart accent, decoration
- brand.primary-strong — text link, outline button (đã Pass ≥ 4.5:1 trên nền page)
- on-primary — chữ trên nút filled (thường trắng hoặc gần đen, Pass trên nền nút)
- hero-overlay — lớp tối/gradient cố định, không phụ thuộc từng frame ảnh
Checklist đàm phán với client (tiếng Việt, ngắn):
- Logo giữ nguyên mã gốc
- Chữ body không dùng mã logo pastel
- CTA filled: nền brand đủ đậm hoặc chữ đậm trên nền nhạt — một trong hai phải Pass
- Hero: luôn có overlay hoặc khối màu đặc dưới chữ
Khi cần đổi nhanh HEX, dùng Color Contrast Checker: chọn foreground / background, xem ratio và Pass/Fail AA·AAA cho chữ thường và chữ lớn. Không cần đăng ký; chạy local trên trình duyệt.
Checklist AA vs AAA trước launch
Bắt buộc (AA) — đừng ship nếu thiếu
- Body và mô tả sản phẩm ≥ 4.5:1 trên nền section
- Label form, error message, placeholder nếu được tính là text ≥ 4.5:1 (placeholder thường bị bỏ qua và hay fail)
- Text trên nút primary / secondary ≥ ngưỡng đúng kích thước
- Link trong đoạn văn phân biệt được không chỉ bằng màu (gạch chân hoặc weight) — màu link vẫn nên ≥ 4.5:1 với nền
- Chữ trên hero / banner đã đo sau overlay
- Hover và focus không làm chữ tụt dưới ngưỡng
Nên làm nếu client yêu cầu AAA hoặc ngành nhạy cảm
- Body ≥ 7:1
- Heading lớn ≥ 4.5:1
- Tránh chữ mỏng (font weight 300) trên nền có texture
UI 3:1 (hay quên)
- Viền input so với nền form
- Icon-only button có nghĩa
- Focus ring đủ rõ (không chỉ
outline: nonerồi quên thay thế)
Case study ngắn: landing phòng khám
Brief: Hero ảnh phòng chờ sáng, chữ trắng “Đặt lịch khám”, CTA cam #FF8A5C, body xám #9CA3AF trên nền trắng.
Kết quả đo lần 1:
- Headline trên vùng cửa sổ: ~2.1:1 → Fail AA
- CTA
#FF8A5C/#FFFFFF: ~2.5:1 → Fail - Body
#9CA3AF/#FFFFFF: ~2.8:1 → Fail
Chỉnh trong 1 buổi:
- Overlay
linear-gradient(transparent, rgba(0,0,0,.65))dưới khối chữ → chữ trắng Pass chữ lớn - CTA đổi nền
#C2410C, chữ#FFFFFF→ ~5.5:1 Pass AA - Body
#4B5563→ ~7.5:1 (bonus gần AAA) - Giữ
#FF8A5Ccho icon và badge “Ưu đãi” (không phải text dài)
Client vẫn nhận ra brand cam; bounce rate mobile giảm vì đọc được dưới nắng.
Quy trình team agency / freelance
- Design: định nghĩa token Pass trong Figma (ghi chú ratio cạnh style)
- Handoff: bảng HEX foreground/background cho từng component
- Dev: không dùng
opacitytrên chữ để “làm dịu” — opacity làm contrast thật khác với HEX đã đo - QA: đo lại trên staging với công cụ contrast + mắt trên thiết bị thật
- Launch: chụp screenshot vùng hero mobile đưa vào checklist bàn giao
Lưu ý kỹ thuật: rgba() / opacity trên parent làm màu hiệu dụng khác mã đã kiểm. Gradient và backdrop-filter cũng vậy — luôn lấy màu đã composite (DevTools eyedropper) rồi mới đo.
Lỗi thường gặp
| Triệu chứng | Nguyên nhân | Cách xử lý |
|---|---|---|
| Figma Pass, web Fail | Font mỏng hơn, antialias, hoặc màu CSS khác token | Đo lại HEX từ computed style |
| Chỉ fail ở ảnh carousel | Mỗi slide độ sáng khác | Overlay cố định hoặc chữ trong khối màu đặc |
| Nút Pass default, Fail hover | Hover làm nền sáng hơn / chữ nhạt hơn | Đo cả :hover và :focus-visible |
| “Chỉ người già mới cần” | Sai — ngoài trời, máy cũ, kính áp tròng đều ảnh hưởng | Giữ AA như chất lượng mặc định |
FAQ nhanh trong review
Khi PM hỏi “có cần AAA không?”: trả lời AA cho toàn site, AAA cho đoạn pháp lý nếu có. Khi brand hỏi “đổi màu có mất nhận diện không?”: chỉ ra logo và illustration giữ nguyên; chỉ text/CTA dùng biến thể mạnh hơn.
Liên kết hữu ích
- Kiểm tra độ tương phản (Color Contrast) — đo AA/AAA ngay trên trình duyệt
- Chuyển HEX / RGB / HSL — chỉnh sáng/tối rồi đo lại
- Danh sách công cụ
Tóm lại: hero đẹp mà chữ không đọc được là lỗi contrast, không phải “khách khó tính”. Đặt AA 4.5:1 làm cổng, tách brand accent khỏi text token, và đo trên nền thật sau overlay trước mọi lần launch.