Bài 27.4: Testing accessibility

Bài 27.4: Testing accessibility
Bạn đã dành thời gian để học về các nguyên tắc xây dựng web accessibility, từ việc sử dụng HTML ngữ nghĩa (semantic HTML), quản lý focus, thêm alt text cho ảnh, đến việc tuân thủ các tiêu chuẩn màu sắc. Nhưng làm sao để biết chắc rằng những nỗ lực đó của bạn thực sự hiệu quả? Đây chính là lúc kiểm thử accessibility phát huy vai trò tối thượng của nó. Xây dựng là một chuyện, đảm bảo nó hoạt động tốt cho mọi người lại là một câu chuyện khác – và kiểm thử chính là cầu nối không thể thiếu.
Tại sao kiểm thử accessibility lại quan trọng?
Không chỉ là làm "đúng luật" (ví dụ: các quy định như WCAG - Web Content Accessibility Guidelines), việc kiểm thử còn giúp bạn:
- Đảm bảo website thực sự có thể sử dụng: Lý thuyết khác với thực tế. Kiểm thử giúp phát hiện những lỗi mà bạn có thể bỏ sót trong quá trình code, những lỗi chỉ xuất hiện khi tương tác thực tế.
- Tiếp cận tập người dùng rộng lớn hơn: Bao gồm người khuyết tật (khiếm thị, khiếm thính, khó khăn vận động, nhận thức), người dùng thiết bị di động trong điều kiện ánh sáng chói, người lớn tuổi, hoặc bất kỳ ai đang sử dụng website trong những ngữ cảnh không lý tưởng (mạng chậm, màn hình nhỏ, chỉ dùng bàn phím).
- Cải thiện trải nghiệm người dùng (UX) cho TẤT CẢ mọi người: Nhiều tính năng accessibility (như cấu trúc nội dung rõ ràng, điều hướng bằng bàn phím hiệu quả) mang lại lợi ích cho tất cả người dùng, làm cho website dễ dùng hơn cho mọi người.
- Giảm thiểu rủi ro pháp lý: Tuân thủ các tiêu chuẩn giúp bạn tránh khỏi các vụ kiện liên quan đến phân biệt đối xử trên môi trường số, điều ngày càng phổ biến ở nhiều quốc gia.
Các Phương Pháp Kiểm Thử Accessibility
Có ba phương pháp chính để kiểm thử accessibility, và cách tốt nhất là kết hợp cả ba để có được bức tranh toàn diện nhất về tính thân thiện của website đối với người dùng:
Kiểm Thử Tự Động (Automated Testing):
- Là gì: Sử dụng công cụ (thường là tiện ích mở rộng của trình duyệt, thư viện code trong môi trường test, hoặc các dịch vụ online) để quét mã nguồn và giao diện hiển thị của trang web, tìm các lỗi accessibility phổ biến dựa trên các quy tắc định sẵn.
- Ưu điểm: Nhanh chóng, dễ tích hợp vào quy trình phát triển (ví dụ: chạy trong CI/CD), phát hiện các lỗi "hiển nhiên" và tuân thủ kỹ thuật (như thiếu
alt
text, thiếu label cho form, thiếu ngôn ngữ trang, tỷ lệ tương phản màu thấp không đạt chuẩn). - Nhược điểm: Chỉ phát hiện được khoảng 30-50% tổng số lỗi accessibility. Công cụ tự động không thể hiểu ngữ cảnh, không kiểm tra được luồng sử dụng bàn phím một cách toàn diện, không đánh giá được khả năng hiểu của nội dung, và không thể mô phỏng trải nghiệm thực tế của người dùng công nghệ hỗ trợ.
- Công cụ phổ biến: Lighthouse (tích hợp sẵn trong Chrome DevTools, cũng có thể chạy bằng dòng lệnh), Axe (tiện ích mở rộng cho trình duyệt, thư viện JavaScript
axe-core
), WAVE (tiện ích mở rộng và website check), Pa11y.
Kiểm Thử Thủ Công (Manual Testing):
- Là gì: Tự tay bạn (hoặc người tester chuyên nghiệp) tương tác với website bằng các phương pháp mô phỏng người dùng khác nhau và kiểm tra từng thành phần, từng luồng công việc.
- Ưu điểm: Phát hiện các lỗi ngữ cảnh phức tạp, kiểm tra luồng sử dụng bàn phím (tab order, focus state), khả năng điều hướng bằng bộ đọc màn hình (screen reader), tính dễ đọc của nội dung, cấu trúc heading logic, và các vấn đề tương tác động khác – những thứ mà công cụ tự động chắc chắn sẽ bỏ sót.
- Nhược điểm: Tốn thời gian hơn đáng kể so với kiểm thử tự động, đòi hỏi người kiểm thử phải có kiến thức nhất định về accessibility, các tiêu chuẩn WCAG và cách sử dụng các công nghệ hỗ trợ cơ bản.
- Các kỹ thuật thủ công chính: Điều hướng bằng bàn phím, sử dụng bộ đọc màn hình, kiểm tra cấu trúc heading, kiểm tra tương phản màu (bằng công cụ chuyên dụng), phóng to trang, tắt CSS/JavaScript.
Kiểm Thử Với Người Dùng Thật (User Testing with People with Disabilities):
- Là gì: Mời những người khuyết tật thật sự (người mù, người khiếm thị, người gặp khó khăn về vận động, người bị rối loạn nhận thức, v.v.) sử dụng website của bạn để thực hiện các tác vụ điển hình và thu thập phản hồi của họ.
- Ưu điểm: Cung cấp góc nhìn thực tế nhất và có giá trị nhất. Họ sẽ phát hiện ra những vấn đề mà ngay cả kiểm thử thủ công chuyên nghiệp cũng khó lòng lường trước được, dựa trên kinh nghiệm sử dụng công nghệ hỗ trợ và các chiến lược tương tác của chính họ. Đây là cách tốt nhất để hiểu liệu website của bạn có thực sự hoạt động tốt cho người dùng mục tiêu hay không.
- Nhược điểm: Khó tổ chức, tốn kém, đòi hỏi sự nhạy bén, tôn trọng và kỹ năng phỏng vấn khi làm việc với người tham gia. Thường được thực hiện ở các giai đoạn sau của dự án hoặc định kỳ để đánh giá mức độ trưởng thành về accessibility.
Những Điều Cần Kiểm Thử Cụ Thể
Khi tiến hành kiểm thử (đặc biệt là thủ công và với người dùng thật), bạn cần chú ý đến các khía cạnh sau. Đây là danh sách những điểm thường gặp vấn đề và cần được kiểm tra kỹ lưỡng:
HTML Ngữ Nghĩa (Semantic HTML):
- Kiểm thử: Sử dụng công cụ tự động để tìm các cảnh báo về cấu trúc, hoặc đơn giản là xem mã nguồn (Inspect Element trong DevTools) hoặc sử dụng tab "Accessibility" trong Chrome/Firefox DevTools để xem cây accessibility tree. Bạn có dùng các thẻ
<nav>
,<main>
,<aside>
,<article>
,<button>
,<input>
,<form>
,<header>
,<footer>
,<h1>
đến<h6>
,<p>
,<ul>
,<ol>
,<li>
đúng mục đích và theo thứ tự logic không? Tránh lạm dụngdiv
vàspan
cho mọi thứ cần ngữ nghĩa hoặc tương tác. - Tại sao: Các thẻ ngữ nghĩa giúp bộ đọc màn hình và các công nghệ hỗ trợ khác hiểu được cấu trúc và vai trò của từng phần trên trang, cho phép người dùng điều hướng hiệu quả hơn (ví dụ: nhảy giữa các heading, tìm phần
main
). Ví dụ: một nút được tạo bằng<button>
có sẵn khả năng focus bằng bàn phím và ngữ nghĩa "nút" (role="button"), trong khi mộtdiv
được làm cho giống nút thì không có những đặc tính này mặc định.
<!-- Tốt: Sử dụng thẻ ngữ nghĩa đúng --> <nav> <ul> <li><a href="/">Trang chủ</a></li> <li><a href="/about">Về chúng tôi</a></li> </ul> </nav> <button onclick="doSomething()"> Gửi thông tin </button> <!-- Không tốt: Lạm dụng div/span --> <!-- <div> <span>Trang chủ</span> <span>Về chúng tôi</span> </div> <div onclick="doSomething()" style="cursor: pointer;"> Gửi thông tin </div> -->
Giải thích: Thẻ
<nav>
báo hiệu đây là phần điều hướng chính. Thẻ<ul>
,<li>
và<a>
tạo ra danh sách liên kết có cấu trúc rõ ràng cho bộ đọc màn hình. Thẻ<button>
tự động xử lý focus và tương tác qua bàn phím. Sử dụngdiv
/span
thay thế làm mất đi ngữ nghĩa và yêu cầu rất nhiều công sức để phục hồi chức năng accessibility.- Kiểm thử: Sử dụng công cụ tự động để tìm các cảnh báo về cấu trúc, hoặc đơn giản là xem mã nguồn (Inspect Element trong DevTools) hoặc sử dụng tab "Accessibility" trong Chrome/Firefox DevTools để xem cây accessibility tree. Bạn có dùng các thẻ
Điều Hướng Bằng Bàn Phím (Keyboard Navigation):
- Kiểm thử: Đây là một trong những bài kiểm thử thủ công quan trọng nhất. Rút chuột ra và chỉ dùng bàn phím (phím Tab để di chuyển tới/lui giữa các thành phần tương tác, Shift + Tab để đi ngược lại, Enter/Space để kích hoạt nút/liên kết, phím mũi tên để di chuyển trong listbox, menu, v.v.).
- Bạn có thể truy cập TẤT CẢ các thành phần tương tác trên trang (liên kết, nút, trường form, các phần tử có thể click/hover mà có chức năng) chỉ bằng bàn phím không?
- Thứ tự Tab có logic và dự đoán được không? (Thường là từ trái sang phải, từ trên xuống dưới theo bố cục hình ảnh).
- Focus state (trạng thái khi một phần tử được chọn bằng bàn phím) có rõ ràng không? (Có thấy viền xanh, highlight, hoặc hiệu ứng khác cho biết bạn đang ở đâu không?). Đừng bao giờ tắt
outline
bằng CSS reset mà không cung cấp focus state thay thế! - Bạn có "mắc kẹt" ở đâu không? (Ví dụ: khi một modal box hoặc menu dropdown mở ra, focus có được đưa vào bên trong không? Bạn có thể Tab ra khỏi modal/menu đó một cách dễ dàng không? Có thể đóng modal/menu bằng phím Escape không?).
- Các thành phần tương tác phức tạp (dropdown, slider, tab panel, custom checkbox/radio) có thể được điều khiển hoàn toàn bằng bàn phím theo các quy ước chuẩn không?
- Tại sao: Nhiều người dùng (người khuyết tật vận động không thể dùng chuột, người dùng bộ đọc màn hình, người dùng chỉ dùng bàn phím vì lý do cá nhân) chỉ sử dụng bàn phím để điều hướng và tương tác với website. Nếu website không hoạt động tốt bằng bàn phím, họ sẽ không thể sử dụng được các chức năng chính.
- Kiểm thử: Đây là một trong những bài kiểm thử thủ công quan trọng nhất. Rút chuột ra và chỉ dùng bàn phím (phím Tab để di chuyển tới/lui giữa các thành phần tương tác, Shift + Tab để đi ngược lại, Enter/Space để kích hoạt nút/liên kết, phím mũi tên để di chuyển trong listbox, menu, v.v.).
Alternative Text cho Ảnh (Alt Text):
- Kiểm thử:
- Sử dụng công cụ tự động (Lighthouse, Axe) để kiểm tra các thẻ
<img>
thiếu thuộc tínhalt
hoặc cóalt
rỗng không hợp lý. - Xem mã nguồn (Inspect Element) hoặc sử dụng bộ đọc màn hình để nghe nội dung của alt text. Alt text có mô tả nội dung hoặc chức năng của ảnh một cách ngắn gọn và hữu ích cho người không nhìn thấy ảnh không?
- Đối với ảnh trang trí (không truyền tải thông tin quan trọng, chỉ để làm đẹp), thuộc tính
alt
nên để trống (alt=""
) để bộ đọc màn hình bỏ qua, tránh làm phiền người dùng.
- Sử dụng công cụ tự động (Lighthouse, Axe) để kiểm tra các thẻ
- Tại sao: Bộ đọc màn hình đọc nội dung của thuộc tính
alt
để truyền tải thông tin hình ảnh tới người dùng khiếm thị. Thiếualt
hoặcalt
vô nghĩa khiến họ không hiểu nội dung ảnh.
<!-- Tốt: Alt text mô tả nội dung quan trọng --> <img src="bieu-do-doanh-thu.png" alt="Biểu đồ cột thể hiện doanh thu tăng trưởng 15% trong quý 3"> <!-- Tốt: Alt rỗng cho ảnh trang trí --> <img src="nen-trang-tri.jpg" alt=""> <!-- Không tốt: Thiếu alt text --> <img src="san-pham-moi.jpg"> <!-- Không tốt: Alt text chỉ lặp lại nội dung đã có hoặc quá dài dòng --> <img src="nut-tim-kiem.png" alt="Nút có biểu tượng kính lúp dùng để tìm kiếm trên website"> <!-- Chỉ cần alt="Tìm kiếm" là đủ -->
Giải thích: Alt text phải cô đọng và truyền tải mục đích hoặc thông tin của ảnh. Alt rỗng báo cho bộ đọc màn hình bỏ qua ảnh không có giá trị thông tin.
- Kiểm thử:
Tương Phản Màu Sắc (Color Contrast):
- Kiểm thử: Sử dụng các công cụ kiểm tra tương phản màu (như WebAIM Contrast Checker, Color Contrast Analyzer - một ứng dụng desktop, hoặc các tính năng tích hợp trong Axe/Lighthouse). Chỉ định màu chữ và màu nền để công cụ tính tỷ lệ tương phản.
- Tại sao: Người dùng khiếm thị, người bị mù màu, hoặc người dùng sử dụng màn hình trong điều kiện ánh sáng khó khăn (ngoài trời nắng) có thể gặp khó khăn cực kỳ khi đọc văn bản nếu màu chữ và màu nền quá giống nhau. WCAG có các tỷ lệ tương phản tối thiểu (AA và AAA) cho văn bản thường và văn bản lớn để đảm bảo khả năng đọc.
Nhãn Cho Trường Form (Form Labels):
- Kiểm thử: Đây là một bài kiểm thử thủ công đơn giản nhưng hiệu quả: Click vào nhãn (
<label>
). Con trỏ nhập liệu (caret) có nhảy vào trường input tương ứng (textbox, checkbox, radio button, file input) không? Hoặc sử dụng công cụ tự động/bộ đọc màn hình để kiểm tra xem nhãn có được liên kết đúng cách với input không. - Tại sao: Thẻ
<label>
liên kết một đoạn văn bản làm nhãn với trường input tương ứng thông qua thuộc tínhfor
của label khớp vớiid
của input. Điều này không chỉ giúp người dùng click vào nhãn để focus vào input (rất hữu ích trên thiết bị di động hoặc cho người dùng gặp khó khăn khi click chính xác vào ô nhỏ) mà còn giúp bộ đọc màn hình đọc nhãn khi focus vào input, cung cấp ngữ cảnh cho người dùng khiếm thị. Sử dụng placeholder không thay thế được label.
```html <!-- Tốt: Sử dụng label liên kết với input --> <label for="tenNguoiDung">Tên người dùng:</label>
<input type="text" id="tenNguoiDung" name="username"><!-- Tốt (với hidden label): Sử dụng sr-only class cho label chỉ hiển thị với bộ đọc màn hình --> <label for="search" class="sr-only">Tìm kiếm:</label> <input type="search" id="search" placeholder="Nhập từ khóa...">
<style>.sr-only { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0, 0, 0, 0); border: 0; }</style>- Kiểm thử: Đây là một bài kiểm thử thủ công đơn giản nhưng hiệu quả: Click vào nhãn (
<!-- Không tốt: Chỉ sử dụng placeholder làm nhãn -->
<!-- <input type="text" placeholder="Tên người dùng:"> -->
<!-- Không tốt: Nhãn không được liên kết đúng (chỉ hiển thị text) -->
<!-- <div>Tên người dùng:</div><input type="text"> -->
```
*Giải thích:* Thuộc tính `for` của `<label>` phải có giá trị trùng khớp với thuộc tính `id` của trường form tương ứng (`<input>`, `<textarea>`, `<select>`).
ARIA Attributes (Accessible Rich Internet Applications):
- Kiểm thử: Sử dụng bộ đọc màn hình hoặc các công cụ kiểm tra ARIA (như Axe, hoặc tab Accessibility trong Chrome DevTools). Kiểm tra xem các thuộc tính
role
,aria-label
,aria-labelledby
,aria-describedby
,aria-expanded
,aria-hidden
,aria-live
, v.v. có được sử dụng đúng mục đích và cung cấp thông tin chính xác không. - Tại sao: ARIA cung cấp các thuộc tính bổ sung để mô tả vai trò, trạng thái, và thuộc tính của các thành phần UI động hoặc các thành phần không phải là HTML ngữ nghĩa chuẩn (ví dụ: một
div
được làm cho giống slider). ARIA giúp bộ đọc màn hình và các công nghệ hỗ trợ khác hiểu rõ hơn về cách tương tác với các thành phần này, cung cấp trải nghiệm tốt hơn cho người dùng. Lưu ý: Quy tắc ARIA đầu tiên là "Nếu bạn có thể sử dụng một phần tử HTML ngữ nghĩa hoặc thuộc tính HTML có sẵn chức năng tương tự với ARIA, hãy sử dụng nó thay vì ARIA". Chỉ sử dụng ARIA khi không thể đạt được accessibility bằng HTML thuần.
<!-- Ví dụ: Nút toggle menu sử dụng ARIA để báo trạng thái --> <button id="menu-toggle" aria-expanded="false" aria-controls="main-menu"> Menu </button> <nav id="main-menu" hidden> <!-- Nội dung menu --> </nav> <!-- Ví dụ: Thông báo trạng thái cho người dùng bộ đọc màn hình --> <div role="status" aria-live="polite"> Đã lưu thành công! </div>
Giải thích:
aria-expanded="false"
báo cho bộ đọc màn hình biết nút này hiện không mở rộng nội dung (menu đang đóng).aria-controls="main-menu"
cho biết nút này điều khiển phần tử cóid="main-menu"
. Khi menu mở ra, JavaScript sẽ đổiaria-expanded
thànhtrue
.role="status"
vàaria-live="polite"
trên div thông báo trạng thái báo cho bộ đọc màn hình tự động đọc nội dung của div này khi nó thay đổi (ví dụ: khi có thông báo "Đã lưu thành công!"), mà không làm gián đoạn quá nhiều luồng đọc hiện tại của người dùng.- Kiểm thử: Sử dụng bộ đọc màn hình hoặc các công cụ kiểm tra ARIA (như Axe, hoặc tab Accessibility trong Chrome DevTools). Kiểm tra xem các thuộc tính
Xử Lý Lỗi Form:
- Kiểm thử: Submit form với các trường bị lỗi (để trống trường bắt buộc, nhập sai định dạng, v.v.). Kiểm tra cả bằng mắt và bằng bộ đọc màn hình.
- Tại sao: Thông báo lỗi có rõ ràng và được liên kết trực tiếp với trường input tương ứng không? Người dùng bộ đọc màn hình có được thông báo về lỗi ngay khi submit form hoặc khi focus vào trường lỗi không? Có thể sử dụng
aria-describedby
để liên kết text mô tả lỗi với trường input. - Ví dụ: Khi submit form mà trường Email bị bỏ trống, website cần hiển thị thông báo lỗi "Email không được để trống". Thông báo này nên được liên kết với input email bằng
aria-describedby
, và input email nên cóaria-invalid="true"
.
Responsive Design và Zoom:
- Kiểm thử: Thay đổi kích thước cửa sổ trình duyệt, kiểm tra trên các thiết bị khác nhau. Quan trọng hơn là zoom text (Ctrl/Cmd + +) lên 200% hoặc 400% (trong cài đặt trình duyệt). Website có bị vỡ layout không? Nội dung có chồng chéo lên nhau, tràn ra ngoài, hoặc trở nên khó đọc/điều hướng không?
- Tại sao: Người dùng khiếm thị hoặc người lớn tuổi có thể cần phóng to trang để đọc được nội dung. Website cần duy trì khả năng sử dụng khi text được zoom lên đáng kể.
Tiêu Đề Trang (Page Title):
- Kiểm thử: Kiểm tra nội dung của thẻ
<title>
trong<head>
. - Tại sao: Tiêu đề trang là thông tin đầu tiên mà bộ đọc màn hình đọc khi người dùng truy cập một trang mới. Nó giúp người dùng định hướng và hiểu nội dung chính của trang. Tiêu đề nên mô tả ngắn gọn và chính xác nội dung của trang hiện tại, và nên có tên website ở cuối.
<!-- Tốt --> <title>Giỏ hàng của bạn - Tên Website</title> <!-- Không tốt --> <title>Trang</title> <title>Chào mừng</title>
- Kiểm thử: Kiểm tra nội dung của thẻ
Tích Hợp Kiểm Thử Vào Quy Trình Phát Triển
Để accessibility không chỉ là "việc thêm vào sau cùng" (và thường bị bỏ qua khi gấp gáp), hãy cố gắng tích hợp kiểm thử vào quy trình làm việc hàng ngày của nhóm phát triển:
- Kiểm tra nhanh cục bộ: Sử dụng tiện ích mở rộng Axe hoặc Lighthouse ngay khi code xong một component hoặc một tính năng để bắt các lỗi tự động. Đây là bước đầu tiên và dễ làm nhất.
- Tích hợp vào CI/CD: Chạy các bài kiểm thử tự động (sử dụng thư viện như
axe-core
hoặccypress-axe
,jest-axe
) trong quy trình tích hợp liên tục (Continuous Integration / Continuous Delivery). Điều này giúp ngăn chặn các lỗi accessibility "rõ ràng" bị đẩy lên môi trường test hoặc production. - Kiểm thử thủ công định kỳ: Dành thời gian (ví dụ: 30 phút đến 1 tiếng mỗi sprint hoặc mỗi tuần) để chỉ dùng bàn phím, thử nghiệm với bộ đọc màn hình (NVDA trên Windows là miễn phí, VoiceOver trên macOS/iOS là tích hợp sẵn) trên các tính năng mới hoặc quan trọng. Lập danh sách kiểm tra các điểm cần kiểm thử thủ công để đảm bảo không bỏ sót.
- Tuyệt vời nhất là User Testing: Nếu có nguồn lực, hãy thực hiện các buổi kiểm thử với người dùng khuyết tật thật sự. Bắt đầu với quy mô nhỏ và mở rộng dần. Phản hồi của họ là vô giá.
Kiểm thử accessibility là một phần không thể thiếu của quy trình phát triển web hiện đại, đảm bảo rằng sản phẩm của bạn thực sự là cho tất cả mọi người. Bằng cách kết hợp kiểm thử tự động để bắt các lỗi kỹ thuật cơ bản và kiểm thử thủ công/người dùng để đánh giá trải nghiệm thực tế, bạn có thể xây dựng nên những website không chỉ đẹp về hình thức mà còn mạnh mẽ về khả năng tiếp cận.
Comments