Skip to content

Khả năng tiếp cận

Mục tiêu của mọi app Tasco là WCAG 2.2 mức AA. Không chỉ cho người khiếm thị: người dùng quen bàn phím nhập liệu nhanh hơn, màn hình cũ hoặc phòng sáng làm màu nhạt khó đọc, và khoảng một phần mười hai nam giới không phân biệt được đỏ và xanh lá. Phần lớn yêu cầu đã có sẵn trong component; trang này ghi phần đã có và phần mỗi màn hình phải tự làm.

Framework đã lo

Hạng mụcCó sẵn
Tương phảnCác cặp chữ/nền component dùng đạt ≥ 4.5:1 ở cả hai chế độ; test của @tasco/theme chặn token làm tụt ngưỡng — xem Màu & tương phản
Phần tử bấm đượcCButton<button> thật; nút ✕ của CTag<button>aria-label
Nút chỉ có icon của coreToolbar CTable, nút thu gọn menu, nút chế độ sáng/tối, thông báo, tài khoản đều có aria-label
Hộp thoạiDrawer lọc và drawer thiết lập của CTable trả focus về nút đã mở khi đóng; thiết lập cột đổi thứ tự được bằng nút ↑↓ thay cho kéo thả
Tiêu đềCPageHeader render tiêu đề trang bằng <h1>
Ngôn ngữLayer đặt <html lang="vi"> để trình đọc màn hình dùng giọng tiếng Việt từ 2.1
Bản địa hoáantdv dùng locale vi_VN: phân trang, chọn ngày, hộp thoại đều bằng tiếng Việt

Mỗi màn hình phải tự làm

Bàn phím

  • Mọi thao tác làm được chỉ bằng bàn phím: Tab đi qua các phần tử theo thứ tự nhìn thấy, Enter/Space kích hoạt, Esc đóng hộp thoại.
  • Phần tử bấm được phải là CButton hoặc liên kết. Không gắn @click lên div, span hay dòng bảng — bàn phím không tới được. Bảng cần mở chi tiết thì đặt liên kết ở cột mã hoặc cột tên.
  • Không tắt viền focus (outline: none) và không dùng tabindex dương.
  • Mở hộp thoại tự dựng thì đưa focus vào hộp thoại; đóng thì trả focus về phần tử đã mở nó.

Nhãn cho trình đọc màn hình

  • Nút chỉ có icon bắt buộc có aria-label nói hành động và đối tượng: aria-label="Xoá đơn DH-0001", không phải "Xoá" lặp lại ở mọi dòng.
  • Ô nhập luôn có nhãn qua CFormItem label. Placeholder không thay được nhãn.
  • Ảnhalt mô tả nội dung; ảnh trang trí để alt="".
  • Liên kết có chữ tự giải thích khi đọc tách khỏi ngữ cảnh: "Xem đơn DH-0001" thay vì "Xem thêm".
  • Một trang một <h1>CPageHeader đã lo; tiêu đề khối dùng CCard title, không tự thêm <h1> thứ hai.

Màu

  • Không dùng màu làm tín hiệu duy nhất: trạng thái có chữ đi kèm (CTag, CStatus), ô lỗi có dòng chữ lỗi, trường bắt buộc có dấu *, xu hướng tăng giảm có mũi tên.
  • Cặp chữ/nền tự đặt ngoài bảng cặp dùng được thì đo tương phản trước — DevTools của trình duyệt hiện tỉ lệ khi chọn màu chữ, hoặc dùng contrastRatioOf của @tasco/theme từ 2.1.
  • Kiểm tra ở cả chế độ tối.

Nội dung động

  • Thao tác xong báo bằng message — có chữ, không chỉ đổi màu một phần tử.
  • Bảng tải lại không đưa focus về đầu trang.
  • Không tự động chuyển trang hay đóng hộp thoại theo thời gian khi người dùng chưa kịp đọc.

Phóng to và màn hình hẹp

  • Trang dùng được khi phóng to 200%: không cắt chữ, không chồng lấn. Bảng rộng cuộn ngang thay vì ép chữ.
  • Không khoá cỡ chữ bằng đơn vị cố định trong CSS của dự án khi có thể dùng token.

Kiểm tra trước khi mở MR

  • [ ] Đi hết luồng chính chỉ bằng bàn phím, luôn thấy phần tử đang focus.
  • [ ] Mọi nút chỉ có icon có aria-label.
  • [ ] Phóng to 200% không vỡ bố cục.
  • [ ] Xem lại ở chế độ tối.
  • [ ] Chạy kiểm tra accessibility tự động (Lighthouse trong DevTools của Chrome, hoặc tiện ích axe DevTools) — sửa hết lỗi mức nghiêm trọng.
  • [ ] Màn hình quan trọng: nghe thử bằng trình đọc màn hình (VoiceOver trên macOS: ⌘ F5; NVDA trên Windows).

Kiểm tra tự động chỉ bắt được một phần lỗi; bàn phím và trình đọc màn hình vẫn phải thử bằng tay.

Cho dev core

  • Storybook của @tasco/ui có panel Accessibility (axe) cho từng story — xem khi thêm hoặc sửa component: pnpm --filter @tasco/ui storybook.
  • Thêm token màu dùng làm chữ thì thêm cặp vào contrastPairs trong @tasco/theme để test khoá tương phản — xem Đổi design token.
  • Component mới có phần tử tương tác tự dựng thì viết test cho thuộc tính ARIA và thứ tự focus, như test của CTag và drawer thiết lập CTable.

Liên quan