Accessibility (a11y) trong thiết kế web là việc đảm bảo người khuyết tật vẫn dùng được site như user thường — bao gồm khuyết tật thị giác, thính giác, vận động, nhận thức. Bài này coverage WCAG 2.2 với 4 nguyên tắc POUR, contrast 4,5:1 vs 3:1, keyboard navigation, ARIA cơ bản, form a11y, và 3 tool test (axe DevTools, WAVE, Lighthouse) đủ cho team dev áp dụng từ project mới.
Đa số luật quốc gia (EU EAA 2025, US Section 508, UK Equality Act 2010) yêu cầu mức AA cho site công cộng. Bỏ qua có thể bị phạt lên tới 75.000 USD/lần vi phạm tại US — riêng năm 2024 có 4000+ vụ kiện liên quan ADA web.
Việt Nam đang pre-legal nhưng nhiều khách quốc tế B2B SaaS, e-commerce export đã require WCAG AA.
4 lý do a11y không còn là feature optional
Accessibility thường bị xem là “nice to have” — feature thêm vào cuối project khi còn budget. Tư duy này dẫn đến site bỏ qua 15-20% user khuyết tật, mất lưu lượng tự nhiên, và rủi ro pháp lý ngày càng cao.
Quy mô user và overlap với SEO
- 1,3 tỷ user khuyết tật toàn cầu: theo WHO 2023, 16% dân số sống chung với một dạng khuyết tật — khuyết tật thị giác chiếm 25% trên 50 tuổi, color blindness 8% nam giới, khuyết tật vận động 4-5% trưởng thành.
- Overlap với SEO best practice: heading hierarchy đúng giúp screen reader navigate và Google hiểu structure — alt text image cho người khiếm thị cũng được Google Image Search đọc — lang attribute giúp screen reader phát âm và Google biết content language.
- Touch target 24×24 WCAG 2.2 mới: tốt cho mobile usability tổng thể không chỉ user khuyết tật — investing a11y payoff cả 3 mặt compliance + SEO + UX.
Rủi ro pháp lý và brand reputation
EU Accessibility Act bắt đầu apply 28/06/2025 cho mọi product/service trên thị trường EU bao gồm website e-commerce, banking, transport. Site không compliant có thể bị block khỏi EU market — phạt theo từng nước, vd Đức tới 100.000 EUR/vi phạm.
Tại US, ADA đã được toà án diễn giải apply cho website từ 2010s — riêng 2024 có 4000+ vụ kiện ADA web theo UsableNet report. Đa số plaintiff thắng hoặc settle 5.000-50.000 USD + remediation cost — pattern định kỳ khắp e-commerce và SaaS.
4 nguyên tắc POUR foundation của WCAG
WCAG tổ chức 86 success criteria theo 4 nguyên tắc viết tắt POUR. Hiểu 4 nguyên tắc này giúp designer/dev áp dụng đúng nguyên lý mà không phải nhớ từng criteria.
Perceivable và Operable
- P — Perceivable cảm nhận được: nội dung phải present qua nhiều sense, không chỉ visual — critical criteria gồm alt text image (1.1.1), caption video (1.2.2), color contrast text 4,5:1 (1.4.3), resize 200% không mất content (1.4.4).
- O — Operable thao tác được: user phải interact được bất kể input device — keyboard navigable (2.1.1), no keyboard trap (2.1.2), skip link navigation (2.4.1), focus visible (2.4.7), touch target 24×24 mới WCAG 2.2 (2.5.8).
Understandable và Robust
- U — Understandable hiểu được: nội dung và UI behavior phải predictable — page có lang attribute (3.1.1), label rõ cho input (3.3.2), error message gợi fix (3.3.3), no auto-context-change (3.2.2), consistent help (3.2.6 mới WCAG 2.2).
- R — Robust bền vững với assistive tech: code phải work với screen reader, voice control, keyboard — valid HTML (4.1.1), name/role/value cho component custom (4.1.2 ARIA đúng), status message announceable (4.1.3 aria-live cho toast).
Designer thường focus P + U, developer focus O + R. Nhưng tốt nhất cả 2 bên hiểu đủ 4 — đầu project nên có “a11y khởi động dự án” 60 phút align team về 4 nguyên tắc và checklist cụ thể cho stack đang dùng.
Color contrast — ngưỡng 4,5:1 và 3:1
Contrast ratio là số đo độ tương phản giữa 2 màu, từ 1:1 (cùng màu) tới 21:1 (đen trên trắng). WCAG quy định 2 ngưỡng cơ bản và 1 ngưỡng cho UI component cần nhớ.
2 ngưỡng AA cho text và UI
- 4,5:1 cho text thường: font size dưới 18px regular hoặc dưới 14px bold — đây là minimum legal cho mọi site công cộng tại EU/US/UK theo WCAG 2.2 AA.
- 3:1 cho text large: từ 18px regular hoặc 14px bold trở lên — text lớn dễ đọc hơn nên ngưỡng nhẹ hơn, áp dụng cho heading, lead paragraph.
- 3:1 cho UI component và graphic: border button, icon, focus indicator, chart line — chi tiết về contrast trong hierarchy thị giác bổ sung góc nhìn perception cho việc chọn màu.
3 cách test contrast
Chrome DevTools là cách nhanh nhất: Inspect element, tab Accessibility, contrast ratio hiện kèm passing/failing AA và AAA. Color Picker trong DevTools cũng tự calculate ratio khi pick màu trực tiếp.
WebAIM Contrast Checker và Stark plugin Figma+Chrome bổ sung khi cần audit batch. Đa số design system 2026 build sẵn contrast check trong CI pipeline — fail PR nếu component mới có cặp text-bg dưới 4,5:1.
3 pitfall contrast phổ biến
- Placeholder text quá mờ: placeholder #999 trên bg #fff cho ratio 2,85:1 fail AA — fix dùng floating label thay placeholder hoặc placeholder ≥4,5:1 như #6b7280 cho ratio 4,83:1.
- Link không đủ contrast với bg: link xanh nhạt #93c5fd trên trắng cho 2,4:1 fail — đặc biệt link trắng trên xanh accent borderline — fix dùng underline + link color đủ dark, test thực tế.
- Text trên image không đủ contrast: hero text trắng trên image có vùng sáng — contrast biến thiên theo pixel — fix gradient overlay đen 30-50% opacity dưới text, hoặc text shadow nhẹ.
Keyboard navigation và focus state visible
Keyboard navigation là yêu cầu cho user không dùng chuột — không chỉ người liệt mà còn power user, screen reader user (đa số screen reader navigate qua keyboard), user touch screen có voice access.
Tab order và focus visible
Tab key di chuyển focus theo DOM order — top to bottom, left to right. Đảm bảo DOM order khớp với visual order, đặc biệt khi floating element CSS không follow DOM như modal trong DOM trước nhưng visual sau header.
Fix bằng focus management JS: khi modal mở, trap focus trong modal, đóng modal thì restore focus về trigger button. Library helper phổ biến gồm focus-trap, react-focus-lock, hoặc native <dialog> element (Chrome 37+, native focus trap).
Focus visible với :focus-visible
WCAG 2.4.7 AA require focus indicator visible cho mọi element interactive. Modern browser default focus là outline xanh — đẹp, accessible, đừng disable bằng outline: none mà không thay thế.
Pattern chuẩn dùng :focus-visible để chỉ show outline khi keyboard focus, không show khi click chuột: button:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; } — outline ngoài border element, đủ contrast 3:1 trên page bg.
Skip link và custom shortcut
- Skip link “Skip to main content”: ẩn khi mouse, hiện khi focus (Tab key đầu tiên) — cho phép user keyboard skip header dài (logo + 12 menu link) đi thẳng vào main content.
- Implementation skip link: link đầu tiên trong DOM,
position: absolute+top: -100px, on:focusthìtop: 0+ z-index cao — code mẫu<a href="#main" class="skip-link">Skip to main content</a>. - Custom keyboard shortcut cho app phức tạp: Cmd/Ctrl+K cho search, Esc để close modal, “/” để focus search — document shortcut trong help modal, tránh override system shortcut như Cmd+S.
Screen reader, ARIA và semantic HTML
Screen reader là phần mềm đọc nội dung trang cho người khiếm thị. Phổ biến gồm NVDA + JAWS (Windows), VoiceOver (macOS/iOS), TalkBack (Android), ChromeVox — mỗi cái hơi khác nhưng đều dựa trên HTML semantic + ARIA attribute.
Semantic HTML trước, ARIA chỉ khi cần
Semantic HTML là 80% công việc a11y. Dùng đúng element thay vì div all: <button> cho action, <a href> cho navigation, <nav> cho menu, <main> cho content chính, <article> cho post, header/footer cho landmark.
Screen reader announce “navigation”, “main content”, “button” tự động khi semantic đúng — không cần thêm ARIA. Nguyên tắc “first rule of ARIA: don’t use ARIA” — trừ khi không có HTML element fit, đừng thêm ARIA vô tội vạ.
ARIA attribute critical khi build custom component
- role và aria-label cho component custom: kết hợp box, tab panel, accordion —
role="tablist",aria-label="Settings tabs"communicate role và name cho screen reader khi semantic HTML không cover. - aria-expanded cho dropdown và accordion: state đóng/mở phải announce qua attribute — screen reader đọc “collapsed” hoặc “expanded” khi user focus vào trigger.
- aria-describedby cho helper text và error: link input với text mô tả bên dưới — screen reader đọc cả label và helper trong cùng announcement, user hiểu context đầy đủ.
Live region cho dynamic content
Toast notification, error message, search result update không trigger page change — screen reader không tự đọc. Dùng aria-live="polite" (đợi user ngừng) hoặc aria-live="assertive" (đọc ngay, cho urgent).
Pattern toast chuẩn: <div role="status" aria-live="polite"> empty trong DOM, JS update content khi toast show — screen reader tự đọc. Đa số React UI library (Radix, Headless UI) build sẵn live region cho toast component.
Form accessibility — 5 pattern fix 90% lỗi
Form là điểm nóng của a11y issue — đa số form trên web fail accessibility check. 5 pattern dưới fix 90% lỗi thường gặp khi audit form e-commerce hoặc B2B SaaS.
- Label rõ cho mọi input: mỗi input phải có visible label link qua
for+idhoặc nested — placeholder KHÔNG thay thế label vì placeholder mất khi user gõ và screen reader không đọc nhất quán. - Required field signal cả visual và screen reader: visual “*” hoặc “(required)” +
requiredattribute hoặcaria-required="true"— kèm helper text “Trường có dấu * là bắt buộc” để clarify. - Fieldset cho group radio và checkbox: “Chọn phương thức thanh toán” với 4 radio (VNPay, MoMo, ZaloPay, COD) phải
<fieldset>+<legend>— screen reader announce legend kèm mỗi option để giữ context. - Error message hữu ích và actionable: inline cạnh field lỗi, link qua
aria-describedby, gợi ý fix cụ thể — sai “Email invalid”, đúng “Email phải có dạng tê[email protected] (vd: [email protected])”. - Không auto-submit khi Tab qua field: form không tự submit khi user Tab (3.2.2 violation) — autofocus đầu trang OK nhưng tránh autofocus deep trong page vì disorienting cho screen reader.
Touch target và pointer accessibility
WCAG 2.2 (October 2023) thêm criteria mới: touch target tối thiểu 24×24 CSS pixel (2.5.8 AA). Trước đây mức này là AAA, bây giờ là AA chuẩn — site mới build phải tuân thủ.
3 cách fix target nhỏ hơn 24×24
Khi target nhỏ hơn 24×24, có 3 cách fix mà không phá visual design. Tăng padding của element là preferred vì giữ nguyên semantic, tăng size visual khi padding không đủ, hoặc dùng pseudo-element ::before/::after mở rộng hit area.
Apple HIG tiếp tục recommend 44×44, Material Design 48×48 — strict hơn WCAG. Đa số design system trade-off ở 40-48px cho mobile và 32-40px cho desktop — chi tiết về touch target trong CTA hierarchy mobile.
Spacing giữa target và drag alternative
- Gap tối thiểu 8px giữa target: 2 button 40×40 đặt sát nhau gap 0 khiến user tap nhầm — 16px tốt hơn cho user tremor (Parkinson, age-related) — pattern nav bottom mobile 5 icon đều spacing không bao giờ dính.
- Alternative cho drag gesture WCAG 2.5.7: user Parkinson không drag được — phải có button alternative (“Move up”, “Move down” thay drag handle) — sortable list nên có cả 2 cho mọi user.
- Pinch zoom không bị block:
maximum-scale=1trong viewport meta là anti-pattern a11y — phải cho user zoom 200% theo WCAG 1.4.4.
Test tools — axe, WAVE, Lighthouse
Audit a11y không thể manual hoàn toàn — phải có tool tự động catch lỗi technical. 3 tool dưới cover 90% audit cần thiết cho team dev nhỏ.
- axe DevTools của Deque: Chrome extension miễn phí — Open DevTools, tab axe, “Scan ALL of my page” — hiện list issue theo severity (Critical, Serious, Moderate, Minor) kèm link fix — industry standard, đa số CI/CD tích hợp axe-core qua jest-axe.
- WAVE của WebAIM: extension hoặc wave.webaim.org — visual overlay icon trên element có vấn đề trực tiếp trong page — tốt cho audit nhanh thiết kế hoặc QA vì không cần đọc list, nhìn page là biết chỗ fail.
- Lighthouse tích hợp DevTools: tab Lighthouse, check Accessibility, Generate report — báo điểm 0-100 + list issue — score 90+ là target chuẩn cho production, kết hợp axe-core + Google internal rules.
Manual test bù 60% còn lại
Tool tự động chỉ catch khoảng 30-40% issue — còn 60% phải manual test. Manual test bắt buộc gồm 4 phần với thời gian estimate cho site 10-15 page.
- Keyboard navigation only: 1 phút/page, navigate hết site bằng Tab/Shift+Tab/Enter/Esc — bắt focus trap, focus invisible, skip link không work.
- Screen reader test với NVDA/VoiceOver: 5-10 phút/page chính, đọc qua hero và form chính — bắt label thiếu, ARIA sai, live region không announce.
- Visual contrast check element không auto: icon, focus state, chart line — Chrome DevTools color picker.
- Zoom 200% test layout responsive: 1 phút/page, browser zoom 200% — bắt text bị cắt, button overlap, scrollbar ngang xuất hiện.
Câu hỏi thường gặp về accessibility
Site nhỏ có cần WCAG AA không?
Tùy thị trường target. Site VN-only chưa có ràng buộc luật cụ thể, nhưng nếu phục vụ user EU/US thì AA là yêu cầu thực tế cho B2B procurement.
Site nhỏ có thể start với 80% AA criteria (covering critical: alt text, contrast, keyboard, label) — không cần 100% từ đầu. Build site mới luôn dễ làm a11y từ đầu hơn retrofit sau 6-12 tháng.
WCAG AA có ngược lại với “đẹp” không?
Không. Đa số site đẹp + premium (Apple, Stripe, Linear, Vercel) đều WCAG AA.
A11y constraint thường thúc đẩy thiết kế tốt hơn.
Color contrast cao đẹp hơn nhợt nhạt, focus state visible đẹp hơn invisible, label rõ đẹp hơn placeholder mờ. Pattern “a11y vs đẹp” là myth từ designer chưa tìm đúng cách dung hoà.
Dùng overlay tool (accessibe, userway) có đủ không?
Không. Overlay tool chèn JS widget claim “1-click WCAG compliant” không fix root cause — chỉ patch surface trong DOM.
Đa số plaintiff đã thắng case dù site có overlay — ADA case Robles v. Domino’s (2019, US Supreme Court) là precedent.
Best practice là fix code thật, không dùng overlay làm thay.
WCAG 2.2 khác gì WCAG 2.1?
WCAG 2.2 (Oct 2023) thêm 9 criteria mới so với 2.1 (2018). Notable nhất là 2.5.8 touch target 24×24 AA, 3.3.7 redundant entry AA (không yêu cầu user nhập lại info đã nhập), 3.2.6 consistent help A.
2.2 backwards compatible 2.1 — site target 2.1 AA cũng cover 80% 2.2, chỉ cần thêm 5-10% effort lên 2.2.
Bao lâu để remediate site đã build xong cho WCAG AA?
Phụ thuộc tình trạng codebase. Site mới build với pattern modern thường gần AA — chỉ cần 1-2 tuần remediate alt text, focus state, contrast tweak.
Site legacy nhiều năm với tech debt thường cần 2-4 tháng — phải refactor component, viết lại form, chỉnh navigation. Estimate cost: 30-100 triệu cho remediation site mid-size 20-30 page.
Tài nguyên và bước tiếp theo
Accessibility không phải feature optional mà là chuẩn bắt buộc cho mọi site phục vụ thị trường có luật a11y (EU, US, UK, Canada) và là chuẩn industry cho B2B procurement. Các bài liên quan trong cụm UI/UX fundamentals:
- Hierarchy thị giác — 5 đòn bẩy + F/Z-pattern dẫn dắt mắt user — contrast là một trong 5 đòn bẩy chính của hierarchy.
- Gestalt trong thiết kế — 6 nguyên tắc psychology cho UI 2026 — figure/ground critical cho focus state visible bắt buộc của a11y.
- Dark mode trong thiết kế — surface elevation và desaturate accent — contrast trong dark mode khác light, accent cần desaturate 10-20%.
- Design system là gì — 4 lớp foundation, component, pattern, guideline — a11y guideline là lớp trên cùng của design system mature.
Cần đội Web22 build site đạt WCAG 2.2 AA với quy trình kiểm tra 4 layer? Thiết kế design system cho thương hiệu tại Web22 bao gồm pattern a11y trong gói: landing page chuẩn AA từ 15-30 triệu, site 10-20 page với full audit + remediation từ 40-80 triệu, document compliance cho khách trong report kết thúc dự án.


