Kiểm soát tiêu điểm bằng chỉ mục thẻ

Các phần tử HTML tiêu chuẩn như <button> hoặc <input> có sẵn tính năng hỗ trợ tiếp cận bằng bàn phím và bạn nên sử dụng các phần tử này bất cứ khi nào có thể. Tuy nhiên, nếu cần tạo các phần tử tương tác tuỳ chỉnh, bạn có thể tạo hành vi dự kiến của người dùng bằng cách thêm tabindex.

Browser Support

  • Chrome: 1.
  • Edge: 12.
  • Firefox: 1.5.
  • Safari: 3.1.

Source

Chỉ thêm tabindex vào nội dung có tính tương tác. Ngay cả khi nội dung quan trọng (chẳng hạn như hình ảnh chính), người dùng trình đọc màn hình vẫn có thể hiểu được nội dung đó mà không cần thêm tiêu điểm.

Tabindex là gì?

Trong trường hợp cần sửa đổi thứ tự thẻ mặc định do các phần tử tích hợp cung cấp, bạn có thể dùng thuộc tính HTML tabindex để đặt rõ ràng vị trí thẻ của một phần tử.

Bạn có thể áp dụng tabindex cho mọi phần tử, mặc dù bạn chỉ nên áp dụng cho các phần tử tương tác và lấy một dải giá trị số nguyên. Với tabindex, bạn có thể chỉ định một thứ tự rõ ràng cho các phần tử trang có thể lấy tiêu điểm, chèn một phần tử không thể lấy tiêu điểm vào thứ tự nhấn phím Tab và xoá các phần tử khỏi thứ tự nhấn phím Tab. Ví dụ:

tabindex="0": Chèn một phần tử vào thứ tự thẻ tự nhiên. Bạn có thể lấy tiêu điểm cho phần tử bằng cách nhấn Tab và có thể lấy tiêu điểm cho phần tử bằng cách gọi phương thức focus() của phần tử đó.

tabindex="-1": Xoá một phần tử khỏi thứ tự thẻ tự nhiên, nhưng phần tử đó vẫn có thể được lấy tiêu điểm bằng cách gọi phương thức focus()

tabindex="5": Mọi tabindex lớn hơn 0 đều đưa phần tử đó lên đầu thứ tự thẻ tự nhiên. Nếu có nhiều phần tử có chỉ mục thẻ lớn hơn 0, thì thứ tự thẻ sẽ bắt đầu từ giá trị thấp nhất lớn hơn 0 và tăng dần. Việc sử dụng tabindex lớn hơn 0 được coi là một mẫu chống lại.

Đảm bảo người dùng có thể truy cập vào các nút điều khiển bằng bàn phím

Một công cụ như Lighthouse rất hữu ích trong việc tự động phát hiện một số vấn đề về khả năng hỗ trợ tiếp cận, tuy nhiên, con người vẫn phải thực hiện một số hoạt động kiểm thử theo cách thủ công.

Hãy thử nhấn phím Tab để di chuyển trên trang web của bạn. Bạn có thể truy cập vào tất cả các chế độ kiểm soát tương tác trên trang không? Nếu không, bạn có thể cần sử dụng tabindex để cải thiện khả năng lấy tiêu điểm của các chế độ kiểm soát đó.

Quản lý tiêu điểm ở cấp trang

Đôi khi, tabindex giúp tạo trải nghiệm liền mạch cho người dùng. Ví dụ: nếu bạn tạo một trang đơn mạnh mẽ với nhiều phần nội dung, trong đó một số nội dung bị ẩn ở các điểm khác nhau trong quá trình tải trang. Điều này có nghĩa là các đường liên kết điều hướng sẽ thay đổi nội dung hiển thị mà không cần làm mới trang.

Trong trường hợp này, hãy xác định vùng nội dung đã chọn và đặt tabindex-1, đồng thời gọi phương thức focus của vùng nội dung đó. Điều này đảm bảo nội dung không xuất hiện theo thứ tự thẻ tự nhiên. Kỹ thuật này, được gọi là quản lý tiêu điểm, giúp ngữ cảnh mà người dùng cảm nhận được đồng bộ hoá với nội dung trực quan của trang web.

Quản lý tiêu điểm trong các thành phần

Trong một số trường hợp, bạn cũng phải quản lý tiêu điểm ở cấp độ thành phần, chẳng hạn như với Phần tử tuỳ chỉnh.

Bạn có thể gặp khó khăn khi xác định hành vi nào của bàn phím cần triển khai. Hướng dẫn Các phương pháp viết ứng dụng Internet phong phú hỗ trợ tiếp cận (ARIA) liệt kê các loại thành phần và những loại thao tác bàn phím mà chúng hỗ trợ.

Chèn một phần tử vào thứ tự nhấn phím tab

Chèn một phần tử vào thứ tự thẻ tự nhiên bằng cách sử dụng tabindex="0". Ví dụ:

<div tabindex="0">Focus me with the TAB key</div>

Để lấy tiêu điểm vào một phần tử, hãy nhấn phím Tab hoặc gọi phương thức focus() của phần tử đó.

Xoá một phần tử khỏi thứ tự thẻ

Xoá một phần tử bằng cách sử dụng tabindex="-1". Ví dụ:

<button tabindex="-1">Can't reach me with the TAB key!</button>

Thao tác này sẽ xoá một phần tử khỏi thứ tự thẻ tự nhiên, nhưng phần tử đó vẫn có thể được lấy tiêu điểm bằng cách gọi phương thức focus() của phần tử đó.

Việc áp dụng tabindex="-1" cho một phần tử không ảnh hưởng đến các phần tử con của phần tử đó; nếu các phần tử con nằm trong thứ tự nhấn phím Tab một cách tự nhiên hoặc do giá trị tabindex, thì chúng vẫn nằm trong thứ tự nhấn phím Tab. Để xoá một phần tử và tất cả các phần tử con của phần tử đó khỏi thứ tự thẻ, hãy cân nhắc sử dụng polyfill inert của WICG. Polyfill mô phỏng hành vi của một thuộc tính inert được đề xuất, giúp ngăn các công nghệ hỗ trợ chọn hoặc đọc các phần tử.

Tránh tabindex > 0

Mọi tabindex lớn hơn 0 sẽ chuyển phần tử lên đầu thứ tự thẻ tự nhiên. Nếu có nhiều phần tử có tabindex lớn hơn 0, thì thứ tự thẻ sẽ bắt đầu từ giá trị thấp nhất lớn hơn 0 và tăng dần.

Việc sử dụng tabindex lớn hơn 0 được coi là một mẫu chống lại vì trình đọc màn hình điều hướng trang theo thứ tự DOM chứ không phải thứ tự phím tab. Nếu bạn cần một phần tử xuất hiện sớm hơn trong thứ tự thẻ, thì phần tử đó phải được di chuyển đến một vị trí sớm hơn trong DOM.

Với Lighthouse, bạn có thể xác định các phần tử có tabindex > 0. Chạy bài kiểm tra Hỗ trợ tiếp cận (Lighthouse > Options > Accessibility) và xem kết quả của bài kiểm tra "Không phần tử nào có giá trị [tabindex] lớn hơn 0".

Sử dụng "tabindex chuyển vùng"

Nếu đang tạo một thành phần phức tạp, bạn có thể cần thêm chế độ hỗ trợ bàn phím ngoài chế độ lấy tiêu điểm. Hãy sử dụng phần tử select tích hợp sẵn khi có thể. Đây là một thành phần có thể lấy tiêu điểm và cho phép dùng các phím mũi tên để hiển thị thêm các lựa chọn có thể chọn.

Để triển khai các chức năng tương tự trong các thành phần của riêng mình, bạn có thể sử dụng một kỹ thuật được gọi là "tabindex di động". Chỉ mục tab di động hoạt động bằng cách đặt tabindex thành -1 cho tất cả các phần tử con, ngoại trừ phần tử hiện đang hoạt động. Sau đó, thành phần này sử dụng một trình nghe sự kiện bàn phím để xác định phím mà người dùng đã nhấn.

Khi điều này xảy ra, thành phần sẽ đặt tabindex của thành phần con được lấy làm tâm điểm trước đó thành -1, đặt tabindex của thành phần con sẽ được lấy làm tâm điểm thành 0 và gọi phương thức focus() trên thành phần đó.

Trước

<div role="toolbar">
  <button tabindex="-1">Undo</button>
  <button tabindex="0">Redo</button>
  <button tabindex="-1">Cut</button>
</div>

Sau

<div role="toolbar">
  <button tabindex="-1">Undo</button>
  <button tabindex="-1">Redo</button>
  <button tabindex="0">Cut</button>
</div>

Các cách truy cập bằng bàn phím

Nếu không chắc chắn về mức độ hỗ trợ bàn phím mà các thành phần tuỳ chỉnh của bạn có thể cần, bạn có thể tham khảo ARIA Authoring Practices 1.1 (Các phương pháp tạo ARIA 1.1). Hướng dẫn này liệt kê các mẫu giao diện người dùng phổ biến và xác định những phím mà các thành phần của bạn nên hỗ trợ.