Menggunakan tabindex

Memodifikasi urutan DOM dengan tabindex

Dave Gash
Dave Gash
Meggin Kearney
Meggin Kearney

Urutan tab default yang disediakan oleh posisi DOM elemen native cukup praktis, namun ada kalanya Anda ingin mengubah urutan tab, dan memindahkan elemen secara fisik di HTML tidak selalu merupakan solusi yang optimal atau bahkan layak. Untuk kasus ini, Anda dapat menggunakan atribut HTML tabindex untuk menetapkan posisi tab elemen secara eksplisit.

Dukungan Browser

  • 1
  • 12
  • 1,5
  • ≤4

Sumber

tabindex dapat diterapkan ke elemen apa pun - meskipun tidak selalu berguna pada setiap elemen - dan menggunakan rentang nilai bilangan bulat. Dengan tabindex, Anda dapat menentukan urutan eksplisit untuk elemen halaman yang dapat difokuskan, menyisipkan elemen yang tidak dapat difokuskan ke dalam urutan tab, dan menghapus elemen dari urutan tab. Contoh:

tabindex="0": Menyisipkan elemen ke dalam urutan tab alami. Elemen dapat difokus dengan menekan tombol Tab, dan elemen dapat difokuskan dengan memanggil metode focus()-nya

<custom-button tabindex="0">Press Tab to Focus Me!</custom-button>

Tekan Tab untuk Memfokuskan Saya

tabindex="-1": Menghapus elemen dari urutan tab alami, tetapi elemen masih dapat difokuskan dengan memanggil metode focus()

// TODO: DevSite - Code sample removed as it used inline event handlers

// TODO: DevSite - Contoh kode dihapus karena menggunakan pengendali peristiwa inline

tabindex="5": Setiap tabindex yang lebih besar dari 0 akan melompatkan elemen ke depan urutan tab alami. Jika ada beberapa elemen dengan tabindex lebih besar dari 0, urutan tab akan dimulai dari nilai terendah yang lebih besar dari nol dan akan terus naik. Menggunakan tabindex yang lebih besar dari 0 dianggap sebagai anti-pola.

<button>I should be first</button>
<button>And I should be second</button>
<button tabindex="5">But I jumped to the front!</button>

Hal ini khususnya berlaku untuk elemen non-input seperti header, gambar, atau judul artikel. Menambahkan tabindex ke jenis elemen tersebut bersifat kontraproduktif. Jika memungkinkan, sebaiknya atur kode sumber Anda agar urutan DOM menyediakan urutan tab yang logis. Jika Anda menggunakan tabindex, batasi ke kontrol interaktif kustom seperti tombol, tab, dropdown, dan kolom teks; yaitu, elemen yang mungkin diharapkan pengguna untuk memberikan input.

Jangan khawatir pengguna pembaca layar akan kehilangan konten penting karena tidak memiliki tabindex. Meskipun konten itu sangat penting, seperti gambar, jika konten bukanlah sesuatu yang dapat berinteraksi dengan pengguna, tidak ada alasan untuk membuatnya dapat difokuskan. Pengguna pembaca layar tetap dapat memahami konten gambar selama Anda memberikan dukungan atribut alt yang sesuai, yang akan segera kami bahas.

Mengelola fokus di tingkat halaman

Berikut adalah skenario di mana tabindex tidak hanya berguna, tetapi juga diperlukan. Anda mungkin membangun satu halaman yang efektif dengan berbagai bagian konten, tidak semuanya terlihat secara bersamaan. Di halaman semacam ini, mengklik link navigasi dapat mengubah konten yang terlihat tanpa memuat ulang halaman.

Jika ini terjadi, Anda mungkin akan mengidentifikasi area konten yang dipilih, memberinya tabindex dari -1 sehingga tidak muncul dalam urutan tab yang alami, dan memanggil metode focus-nya. Teknik ini, yang disebut mengelola fokus, membuat konteks yang dirasakan pengguna tetap sinkron dengan konten visual situs.

Mengelola fokus dalam komponen

Mengelola fokus saat Anda mengubah sesuatu di halaman itu penting, tetapi terkadang Anda perlu mengelola fokus di tingkat kontrol — misalnya, jika Anda membuat komponen kustom.

Pertimbangkan elemen select native. Elemen ini dapat menerima fokus dasar, tetapi setelah ada, Anda dapat menggunakan tombol panah untuk menampilkan fungsi tambahan (opsi yang dapat dipilih). Jika mem-build elemen select kustom, Anda mungkin ingin mengekspos jenis perilaku yang sama ini sehingga pengguna yang terutama mengandalkan keyboard masih dapat berinteraksi dengan kontrol Anda.

<!-- Focus the element using Tab and use the up/down arrow keys to navigate -->
<select>
    <option>Aisle seat</option>
    <option>Window seat</option>
    <option>No preference</option>
</select>

Mungkin sulit mengetahui perilaku keyboard mana yang akan diterapkan, tetapi ada dokumen bermanfaat yang dapat Anda pelajari. Panduan Praktik Penulisan Aplikasi Internet Kaya yang Dapat Diakses (ARIA) mencantumkan jenis komponen dan jenis tindakan keyboard yang didukung. Kita akan membahas ARIA secara lebih detail nanti, tetapi untuk saat ini, mari kita gunakan panduan ini untuk membantu kita menambahkan dukungan keyboard ke komponen baru.

Mungkin Anda sedang mengerjakan beberapa Elemen Kustom baru yang menyerupai sekumpulan tombol pilihan, tetapi dengan tampilan dan perilaku yang unik.

<radio-group>
    <radio-button>Water</radio-button>
    <radio-button>Coffee</radio-button>
    <radio-button>Tea</radio-button>
    <radio-button>Cola</radio-button>
    <radio-button>Ginger Ale</radio-button>
</radio-group>

Untuk menentukan jenis dukungan keyboard yang mereka butuhkan, Anda dapat melihat Panduan Praktik Penulisan ARIA. Bagian 2 berisi daftar pola desain, dan dalam daftar tersebut terdapat tabel karakteristik untuk grup radio, komponen yang ada dan paling cocok dengan elemen baru.

Seperti yang dapat Anda lihat pada tabel, salah satu perilaku keyboard umum yang harus didukung adalah tombol panah atas/bawah/kiri/kanan. Untuk menambahkan perilaku ini ke komponen baru, kita akan menggunakan teknik yang disebut roving tabindex.

Cuplikan spesifikasi W3C untuk tombol pilihan.

Roving tabindex berfungsi dengan menetapkan tabindex ke -1 untuk semua turunan kecuali yang saat ini aktif.

<radio-group>
    <radio-button tabindex="0">Water</radio-button>
    <radio-button tabindex="-1">Coffee</radio-button>
    <radio-button tabindex="-1">Tea</radio-button>
    <radio-button tabindex="-1">Cola</radio-button>
    <radio-button tabindex="-1">Ginger Ale</radio-button>
</radio-group>

Komponen ini kemudian menggunakan pemroses peristiwa keyboard untuk menentukan tombol mana yang ditekan pengguna; saat ini terjadi, komponen akan menyetel tabindex turunan yang sebelumnya difokuskan ke -1, menetapkan tabindex turunan yang akan difokuskan ke 0, dan memanggil metode fokus di dalamnya.

<radio-group>
    // Assuming the user pressed the down arrow, we'll focus the next available child
    <radio-button tabindex="-1">Water</radio-button>
    <radio-button tabindex="0">Coffee</radio-button> // call .focus() on this element
    <radio-button tabindex="-1">Tea</radio-button>
    <radio-button tabindex="-1">Cola</radio-button>
    <radio-button tabindex="-1">Ginger Ale</radio-button>
</radio-group>

Saat pengguna mencapai turunan terakhir (atau yang pertama, bergantung pada arah mereka memindahkan fokus), Anda akan memutar balik dan memfokuskan kembali turunan pertama (atau terakhir).

Anda dapat mencoba contoh yang sudah selesai di bawah ini. Periksa elemen di DevTools untuk mengamati pergerakan tabindex dari satu tombol radio ke tombol berikutnya.

Perairan Kopi Teh Cola Ginger Ale

// TODO: DevSite - Contoh kode dihapus karena menggunakan pengendali peristiwa inline

Anda dapat melihat sumber lengkap elemen ini di GitHub.

Modal dan perangkap keyboard

Terkadang saat mengelola fokus, Anda bisa masuk ke situasi yang tidak bisa Anda tinggalkan. Pertimbangkan widget pelengkapan otomatis yang mencoba mengelola fokus dan merekam perilaku tab, tetapi mencegah pengguna keluar dari widget hingga selesai. Hal ini disebut jebakan keyboard, dan bisa sangat menjengkelkan bagi pengguna. Bagian 2.1.2 dari checklist tampil di web untuk mengatasi masalah ini, yang menyatakan bahwa fokus keyboard tidak boleh terkunci atau terjebak pada satu elemen halaman tertentu. Pengguna harus dapat menavigasi ke dan dari semua elemen halaman hanya dengan menggunakan keyboard.

Aneh, ada kalanya perilaku ini benar-benar diinginkan, seperti di jendela modal. Biasanya, saat modal ditampilkan, Anda tidak ingin pengguna mengakses konten di belakangnya. Anda dapat menambahkan overlay untuk menutupi halaman secara visual, tetapi hal tersebut tidak menghentikan fokus keyboard keluar dari modal secara tidak sengaja.

Jendela modal yang meminta pengguna untuk menyimpan pekerjaan mereka.

Dalam kasus seperti ini, Anda dapat mengimplementasikan perangkap keyboard sementara untuk memastikan bahwa Anda menangkap fokus hanya saat modal ditampilkan, lalu memulihkan fokus ke item yang sebelumnya difokuskan saat modal ditutup.

Ada beberapa proposal tentang cara mempermudah developer, termasuk elemen <dialog>, tetapi mereka belum mendapatkan dukungan browser yang luas.

Lihat artikel MDN ini untuk informasi selengkapnya tentang <dialog>, dan contoh modal ini untuk informasi selengkapnya tentang jendela modal.

Pertimbangkan dialog modal yang direpresentasikan oleh div yang berisi beberapa elemen, dan div lain yang mewakili overlay latar belakang. Mari kita pelajari langkah-langkah dasar yang diperlukan untuk menerapkan perangkap keyboard sementara dalam situasi ini.

  1. Dengan document.querySelector, pilih div modal dan overlay, serta simpan referensinya.
  2. Saat modal terbuka, simpan referensi ke elemen yang difokuskan saat modal dibuka sehingga Anda dapat mengembalikan fokus ke elemen tersebut.
  3. Gunakan pemroses keydown untuk mengambil tombol saat ditekan saat modal terbuka. Anda juga dapat memproses klik di overlay latar belakang, dan menutup modal jika pengguna mengkliknya.
  4. Selanjutnya, dapatkan kumpulan elemen yang dapat difokuskan dalam modal. Elemen pertama dan terakhir yang dapat difokuskan akan bertindak sebagai "sentinel" untuk memberi tahu Anda kapan harus melakukan loop fokus ke depan atau ke belakang agar tetap berada di dalam modal.
  5. Menampilkan jendela modal dan memfokuskan elemen pertama yang dapat difokuskan.
  6. Saat pengguna menekan Tab atau Shift+Tab, pindahkan fokus ke depan atau ke belakang, dengan melakukan loop pada elemen terakhir atau pertama yang sesuai.
  7. Jika pengguna menekan Esc, tutup modal. Hal ini sangat membantu karena memungkinkan pengguna menutup modal tanpa mencari tombol tutup tertentu, dan hal ini menguntungkan bahkan bagi pengguna yang menggunakan mouse.
  8. Saat modal ditutup, sembunyikan overlay dan overlay latar belakang, serta pulihkan fokus ke elemen yang sebelumnya difokuskan dan telah disimpan sebelumnya.

Prosedur ini memberi Anda jendela modal yang dapat digunakan dan tidak mengecewakan, yang dapat digunakan semua orang secara efektif.

Untuk mengetahui detail selengkapnya, Anda dapat memeriksa kode contoh ini, dan melihat contoh langsung dari halaman lengkap.