Pengguna keyboard menelusuri halaman dengan tombol Tab, dan satu-satunya petunjuk bagi mereka tentang posisi saat ini adalah indikator fokus yang berpindah dari satu elemen ke elemen berikutnya. Masalahnya, pseudo-class :focus
tidak membedakan asal fokus: klik mouse dan tekanan Tab menyalakan aturan yang sama, sehingga cincin tebal tampil juga bagi pengguna mouse yang tidak membutuhkannya. Pseudo-class :focus-visible
memecah persoalan tersebut — browser menilai sendiri kapan indikator benar-benar perlu tampil. Pada Chapter ini kita membedakan keduanya, merancang indikator yang tetap ada, lalu melatih cara mengujinya dengan keyboard.
Perbedaan :focus dan :focus-visible #
:focus cocok dengan elemen yang sedang difokuskan, apa pun penyebabnya: klik, Tab, atau pemanggilan focus() dari skrip. :focus-visible menyerahkan keputusan kepada browser: aturan hanya berlaku bila browser menilai indikator fokus memang harus terlihat. Tabel berikut merangkum perilaku umumnya:
| Cara memfokuskan | :focus | :focus-visible |
|---|---|---|
| Klik mouse pada tombol | cocok | umumnya tidak |
| Tekan Tab ke elemen | cocok | cocok |
| Klik atau Tab ke input teks | cocok | cocok |
| Fokus dipindahkan lewat skrip | cocok | dinilai browser |
Heuristiknya ringkas: pada elemen isian teks, kursor teks memang harus terlihat sehingga fokus selalu dianggap visible. Pada tombol dan tautan, klik mouse dianggap sinyal bahwa pengguna memakai pointer dan tidak memerlukan cincin; tekanan Tab sebaliknya adalah sinyal keyboard yang wajib ditanggapi dengan indikator.
Merancang Indikator Fokus #
Indikator paling aman dibangun dari outline karena digambar di luar kotak tanpa menggeser elemen di sekitarnya — berbeda dengan border yang mengubah layout (perbedaan lengkapnya dibahas pada Chapter Outlines ):
.tombol {
background-color: rgb(37, 99, 235);
color: rgb(255, 255, 255);
border: none;
border-radius: 8px;
padding: 10px 18px;
font: inherit;
}
.tombol:focus-visible {
outline: 3px solid rgb(37, 99, 235);
outline-offset: 2px;
}- Baris 1–7 (
.tombol): gaya dasar tombol tanpa outline apa pun, sehingga gaya fokus sepenuhnya ditentukan aturan berikutnya. - Baris 9–12 (
:focus-visible): cincin biru 3px solid denganoutline-offset: 2px— celah 2px antara tepi tombol dan cincin membuat keduanya tidak menyatu. - Pembagian pengalaman: pengguna mouse mengeklik tombol tanpa melihat cincin; pengguna keyboard mendapat cincin penuh. Satu aturan, dua pengalaman yang tepat sasaran.
Hasil di Browser:
Tombol dalam keadaan diam tampil dengan latar rgb(37, 99, 235), teks putih,
dan sudut 8px — tanpa cincin fokus.
Kotak pembanding pada demo menampilkan outline statis 3px solid rgb(37, 99, 235)
dengan offset 2px, nilai identik dengan aturan :focus-visible pada tombol.
Input teks berborder rgb(203, 213, 225) dalam keadaan dasar.Probe otomatis tidak dapat menekan Tab, sehingga demo menyertakan kotak pembanding yang outline-nya selalu aktif dengan nilai yang sama persis dengan aturan :focus-visible.
Menguji dengan Keyboard #
Langkah manual berikut memverifikasi perilaku yang tidak dapat dijangkau probe:
- Buka demo, lalu klik tombol dengan mouse — fokus pindah ke tombol (
:focusaktif), tetapi cincin umumnya tidak tampil karena browser menilai pengguna pointer tidak memerlukannya. - Tekan Tab beberapa kali — setiap elemen yang menerima fokus menampilkan cincin biru 3px dengan celah 2px.
- Klik input teks — cincin tetap tampil: elemen isian selalu memicu
:focus-visiblekarena kursor teks harus terlihat.
Saat menyempurnakan desain, panel DevTools dapat memaksa keadaan fokus tanpa keyboard: pilih elemen di tab Elements, buka menu Force state, lalu centang :focus-visible. Gunakan cara ini untuk iterasi visual, dan simpan pengujian akhir untuk keyboard sungguhan agar urutan Tab ikut diperiksa — fokus sebaiknya berpindah mengikuti urutan visual halaman, bukan melompat ke elemen yang jauh di belakang.