2.1.2 No Keyboard Trap (mức A): nếu focus vào được một vùng bằng bàn phím thì cũng phải ra được bằng bàn phím, dùng phím thông thường (Tab, Shift+Tab, mũi tên). Nếu cần phím đặc biệt để thoát thì phải nói cho người dùng biết trước.
Ba nguồn trap hay gặp trong app React:
- Modal tự viết giữ focus bên trong nhưng quên xử lý Escape và quên nút đóng có thể Tab tới.
- Editor nhúng (CodeMirror, Monaco, canvas) nuốt phím Tab để chèn thụt lề. Cách xử lý chuẩn: Escape rồi Tab để thoát, và ghi hướng dẫn ngay cạnh editor.
- Widget nhúng iframe của bên thứ ba — quảng cáo, chat, video player.
// trap không cố ý: bắt Tab mà không có đường ra
editor.addEventListener('keydown', (e) => {
if (e.key === 'Tab') { e.preventDefault(); insertTab() }
})2.4.3 Focus Order (mức A) là tiêu chí khác: thứ tự nhận focus phải giữ được nghĩa và thao tác được, không bắt buộc trùng khít thứ tự thị giác. Nhưng lệch nhiều thì gần như chắc chắn trượt, vì người dùng mất mạch.
Nguyên nhân lệch phổ biến nhất là CSS đổi thứ tự hiển thị mà DOM giữ nguyên: order trong flex, grid-area, flex-direction: row-reverse, position: absolute kéo phần tử lên đầu màn hình. Tab đi theo DOM, mắt đi theo CSS.
Lưu ý: đừng chữa bằng tabindex dương (tabindex="1") — nó nhấc phần tử lên trước toàn bộ tab order tự nhiên của trang và rất khó bảo trì. Sửa bằng cách xếp lại DOM.
Cách kiểm: rút chuột, Tab từ đầu tới cuối trang. Focus ring phải luôn nhìn thấy, đi theo thứ tự đọc, và quay ra được thanh địa chỉ của trình duyệt.