Mở đầu — vì sao bài này quan trọng
Bạn có thể là một designer hay developer giỏi về accessibility (a11y): bạn hiểu ARIA, biết cách kiểm tra bằng screen reader, làm được focus indicator đẹp. Nhưng nếu tất cả kiến thức đó chỉ nằm trong đầu bạn, thì mỗi khi có người mới vào team, mỗi khi khách hàng hỏi "sản phẩm của các bạn có tuân thủ chuẩn accessibility không?", hay mỗi khi một component bị dùng sai cách — thì công sức của bạn sẽ tan biến.
Đó chính là lý do bài học này ra đời. Accessibility không phải là việc làm một lần rồi xong; nó là một trạng thái cần được duy trì. Và cách duy nhất để duy trì ở quy mô tổ chức là viết nó ra thành tài liệu. Có hai loại tài liệu bạn cần nắm vững:
- Internal docs (tài liệu nội bộ) — dành cho chính team của bạn: designer, dev, QA, PM. Mục tiêu là để mọi người xây sản phẩm đúng ngay từ đầu, không phải sửa sau.
- VPAT (Voluntary Product Accessibility Template) — một tài liệu chuẩn hóa dành cho bên ngoài: khách hàng, bộ phận mua sắm (procurement), cơ quan chính phủ. Đây là "hồ sơ khai báo mức độ tuân thủ" chính thức của sản phẩm.
Khái niệm cốt lõi
Internal docs — Tài liệu accessibility nội bộ
Tài liệu nội bộ tốt phải trả lời được câu hỏi: "Làm sao để người tiếp theo xây đúng mà không cần hỏi tôi?" Có ba tầng tài liệu chính.
1. Trang accessibility cho từng component (Component a11y page)
Đây là phần quan trọng nhất trong một design system. Với mỗi component (button, modal, dropdown, tabs...), bạn viết một trang mô tả gồm:
- Anatomy (giải phẫu): sơ đồ trực quan của component, chú thích rõ đâu là phần hiển thị và đâu là phần accessibility (ví dụ: nút X đóng modal cần có
aria-label="Đóng", vùng nội dung cầnrole="dialog"). - ARIA pattern reference: link tới mẫu chuẩn tương ứng trong tài liệu WAI-ARIA Authoring Practices Guide (APG) của W3C. Bạn không tự bịa ra pattern; bạn tham chiếu tới nguồn đã được cộng đồng công nhận.
- Keyboard interaction (tương tác bàn phím): bảng liệt kê từng phím và hành vi mong đợi. Ví dụ với modal:
Escđể đóng,Tabđể di chuyển trong focus trap, focus quay về nút đã mở modal khi đóng. - States & properties: các trạng thái ARIA cần quản lý (
aria-expanded,aria-selected,aria-disabled...) và khi nào chúng thay đổi. - Do / Don't: ví dụ dùng đúng và dùng sai, kèm ảnh chụp.
Đây là "hiến pháp" accessibility của tổ chức: mức chuẩn cam kết (thường là WCAG 2.1 mức AA), color palette đã được kiểm tra contrast, quy tắc viết alt text, checklist review trước khi merge code, quy trình khi phát hiện bug.
3. Decision log (nhật ký quyết định)
Ghi lại những quyết định khó và lý do. Ví dụ: "Chúng ta chọn không dùng tooltip cho thông tin quan trọng vì tooltip không truy cập được bằng bàn phím trên touch device — thay vào đó dùng text mô tả cố định." Log này giúp team mới không lặp lại tranh luận cũ.
VPAT — Voluntary Product Accessibility Template
VPAT là một mẫu tài liệu do ITI (Information Technology Industry Council) tạo ra, dùng để khai báo mức độ tuân thủ accessibility của một sản phẩm. Khi bạn điền xong VPAT, kết quả gọi là ACR (Accessibility Conformance Report) — nhưng trong thực tế nhiều người vẫn gọi chung là "VPAT".
Có bốn phiên bản (Editions) của VPAT, bạn chọn theo thị trường:
- VPAT WCAG — chỉ theo chuẩn WCAG (dùng phổ biến nhất trên toàn cầu).
- VPAT 508 — theo Section 508 của luật Mỹ (bán cho cơ quan liên bang Mỹ).
- VPAT EU — theo chuẩn EN 301 549 của châu Âu.
- VPAT INT (International) — gộp cả ba, dùng khi bán đa thị trường.
- Supports — sản phẩm đáp ứng đầy đủ tiêu chí này.
- Partially Supports — đáp ứng một phần, còn một số chỗ chưa đạt (phải giải thích rõ chỗ nào).
- Does Not Support — không đáp ứng.
- Not Applicable — tiêu chí không liên quan tới sản phẩm (ví dụ: tiêu chí về video caption cho một sản phẩm không có video).
Một nguyên tắc đạo đức nghề nghiệp cực kỳ quan trọng: VPAT phải trung thực. Khai "Supports" trong khi sản phẩm không đạt là hành vi có thể dẫn tới rủi ro pháp lý (bị kiện vì gian dối) và mất uy tín. Một VPAT trung thực ghi "Partially Supports" kèm kế hoạch khắc phục có giá trị hơn nhiều một VPAT toàn "Supports" giả tạo.
Tình huống thực tế
Tình huống 1 — Startup SaaS Việt Nam trượt hợp đồng vì thiếu VPAT
Một công ty SaaS ở TP.HCM, tạm gọi là HanaWork (nền tảng quản lý nhân sự), tham gia đấu thầu cung cấp phần mềm cho một tập đoàn đa quốc gia có văn phòng ở Singapore. Sản phẩm của họ tốt, giá cạnh tranh, demo mượt. Nhưng trong bộ hồ sơ RFP (Request for Proposal), bên mua yêu cầu một dòng ngắn gọn: "Please attach your latest VPAT/ACR."
HanaWork không có tài liệu này, và cũng không hiểu nó là gì. Họ trả lời "sản phẩm của chúng tôi thân thiện với người dùng" — một câu trả lời vô nghĩa với bộ phận procurement. Kết quả: hồ sơ bị loại ở vòng sơ tuyển kỹ thuật, dù chưa ai chê một tính năng nào.
Bài học rút ra: Ở thị trường B2B enterprise, VPAT là "vé vào cửa", không phải điểm cộng. Bạn không cần đạt 100% "Supports" để có VPAT — bạn cần có một VPAT trung thực. Sáu tháng sau, HanaWork thuê một chuyên gia audit, làm VPAT WCAG với khoảng 60% tiêu chí "Supports" và phần còn lại là "Partially Supports" kèm roadmap. Chính bản VPAT "chưa hoàn hảo nhưng minh bạch" đó đã giúp họ qua vòng ở lần đấu thầu tiếp theo.
Tình huống 2 — Component page cứu team design system của một ngân hàng
Một ngân hàng số tại Đông Nam Á xây design system nội bộ. Ban đầu, mỗi squad tự làm dropdown theo cách riêng: có squad dùng <div> giả làm dropdown (không truy cập được bằng bàn phím), có squad quên aria-expanded. Kết quả là mỗi lần audit lại phát hiện cùng một loại lỗi ở chỗ khác nhau — sửa hoài không hết.
Team design system quyết định viết component a11y page cho từng thành phần. Với dropdown, họ ghi rõ: anatomy, tham chiếu tới ARIA APG pattern "Combobox", bảng keyboard (mũi tên lên/xuống để chọn, Enter để xác nhận, Esc để đóng, Home/End để nhảy đầu/cuối), và các state aria-expanded, aria-activedescendant. Kèm theo là một component code đã đóng gói sẵn.
Sau ba tháng, số bug accessibility liên quan tới dropdown trong các đợt audit giảm khoảng 80%. Không phải vì dev giỏi hơn, mà vì họ có một nguồn chân lý duy nhất để tham chiếu và một component chuẩn để tái sử dụng.
Bài học rút ra: Tài liệu component a11y không phải để "trang trí". Nó là công cụ ngăn lỗi xảy ra ở quy mô lớn. Một trang tài liệu tốt viết một lần, tiết kiệm hàng trăm giờ sửa bug về sau.
Tình huống 3 — VPAT khai gian và cái giá phải trả
Một nhà cung cấp phần mềm giáo dục (giả định tên EduPlus) bán hệ thống LMS cho một trường đại học công lập ở Mỹ. Để thắng thầu nhanh, họ điền VPAT với gần như toàn bộ tiêu chí là "Supports", dù thực tế sản phẩm có nhiều lỗi: form không có label, video không có caption.
Sau khi triển khai, một sinh viên khiếm thị không dùng được hệ thống nộp bài. Nhà trường đối chiếu lại VPAT, phát hiện các tiêu chí đã khai "Supports" thực chất không đạt. Hợp đồng bị chấm dứt, EduPlus phải hoàn tiền và bị đưa vào "danh sách đen" của mạng lưới các trường — mất luôn cơ hội bán cho hàng chục trường khác.
Bài học rút ra: VPAT là một tuyên bố có tính ràng buộc. Trung thực không chỉ là đạo đức mà còn là chiến lược kinh doanh dài hạn. "Partially Supports" trung thực luôn tốt hơn "Supports" gian dối.
Hướng dẫn từng bước
Phần A — Viết một component a11y page
- Chọn nguồn chân lý. Với mỗi component, tìm pattern tương ứng trong WAI-ARIA APG (
w3.org/WAI/ARIA/apg). Đừng tự nghĩ ra pattern. - Vẽ anatomy. Chụp ảnh component, chú thích cả phần nhìn thấy lẫn phần a11y (label ẩn, role, live region).
- Lập bảng keyboard. Liệt kê từng phím và hành vi. Đây là phần dev hay bỏ sót nhất.
- Liệt kê states & properties. Ghi rõ mỗi ARIA state đổi giá trị khi nào.
- Thêm Do/Don't. Ít nhất một ví dụ đúng và một ví dụ sai.
- Đặt cạnh code. Lý tưởng nhất là trang tài liệu nằm ngay trong Storybook hoặc trang design system, đứng cạnh component thật.
Phần B — Tạo một VPAT
- Tải mẫu mới nhất từ website của ITI. Chọn đúng Edition (WCAG / 508 / EU / INT) theo thị trường mục tiêu.
- Điền thông tin sản phẩm: tên, phiên bản, ngày đánh giá, phương pháp đánh giá (tự động, thủ công, screen reader nào...).
- Audit thật trước khi điền. Đây là bước quan trọng nhất. Dùng công cụ tự động (axe, WAVE) kết hợp kiểm tra thủ công bằng bàn phím và screen reader cho từng tiêu chí WCAG.
- Điền Conformance Level cho từng tiêu chí: Supports / Partially Supports / Does Not Support / Not Applicable.
- Viết cột Remarks cẩn thận. Với mỗi "Partially Supports", nêu rõ chỗ nào chưa đạt và (nếu có) kế hoạch khắc phục.
- Rà soát bởi người thứ hai. VPAT nên được một chuyên gia a11y kiểm tra lại để tránh khai sai.
- Đặt lịch cập nhật. VPAT gắn với một phiên bản sản phẩm; mỗi bản release lớn cần cập nhật lại.
Lỗi thường gặp & mẹo
- Viết tài liệu rồi để đó, không ai đọc. Mẹo: đặt component a11y page ngay cạnh code (trong Storybook / design system site), không để trong một file Google Docs riêng lẻ bị lãng quên.
- VPAT đánh dấu "Supports" hàng loạt cho nhanh. Đây là lỗi nguy hiểm nhất. Mẹo: coi mỗi ô "Supports" như một lời cam kết có thể bị kiểm chứng — chỉ đánh dấu khi bạn đã tự tay test.
- Nhầm "Not Applicable" với "Does Not Support". "Not Applicable" nghĩa là tiêu chí không liên quan (sản phẩm không có video thì tiêu chí caption là N/A). Đừng dùng N/A để né tránh một tiêu chí thực sự áp dụng nhưng chưa đạt.
- Bỏ trống cột Remarks. Người đọc chuyên nghiệp đánh giá bạn qua phần giải thích. Một "Supports" không kèm giải thích kém thuyết phục hơn "Partially Supports" có mô tả rõ ràng.
- VPAT lỗi thời. Mẹo: ghi rõ phiên bản sản phẩm và ngày trên VPAT; gắn việc cập nhật VPAT vào quy trình release.
- Component page thiếu bảng keyboard. Đây là phần bị bỏ sót nhiều nhất và cũng là nguồn gây lỗi a11y phổ biến. Luôn có bảng keyboard.
- Copy VPAT của sản phẩm khác. Mỗi sản phẩm khác nhau; VPAT phải phản ánh đúng thực trạng của chính sản phẩm bạn.
Bài tập thực hành
- Viết một component a11y page hoàn chỉnh cho component Modal / Dialog. Bao gồm đủ 5 phần: anatomy (có chú thích role và aria-label), tham chiếu ARIA APG pattern "Dialog (Modal)", bảng keyboard (tối thiểu: Esc đóng, Tab trong focus trap, focus return), danh sách states, và một cặp Do/Don't.
- Điền thử một phần VPAT. Chọn 5 tiêu chí WCAG mức A/AA (ví dụ: 1.1.1 Non-text Content, 1.4.3 Contrast, 2.1.1 Keyboard, 2.4.7 Focus Visible, 4.1.2 Name Role Value). Với một trang web bất kỳ mà bạn hay dùng, tự đánh giá và điền Conformance Level cho từng tiêu chí, kèm cột Remarks giải thích vì sao. Chú trọng viết Remarks trung thực và cụ thể.
- Viết một mục trong decision log. Ghi lại một quyết định a11y giả định của team (ví dụ: "không dùng placeholder thay cho label") kèm lý do và ngày tháng, theo đúng tinh thần nhật ký quyết định.
Tóm tắt
Accessibility chỉ bền vững khi được viết ra thành tài liệu. Có hai loại tài liệu bạn phải nắm:
- Internal docs giúp team xây đúng ngay từ đầu — quan trọng nhất là component a11y page (anatomy, ARIA pattern reference, bảng keyboard, states, Do/Don't), cộng với guideline chung và decision log.
- VPAT/ACR là tài liệu chuẩn hóa khai báo mức tuân thủ cho bên ngoài — chọn đúng Edition (WCAG/508/EU/INT), đánh giá mỗi tiêu chí bằng bốn mức Supports / Partially Supports / Does Not Support / Not Applicable, và viết cột Remarks thật cẩn thận.