Pengguna yang menavigasi halaman dengan keyboard tidak memiliki kursor panah: satu-satunya cara mereka mengetahui elemen mana yang sedang aktif adalah melihat indikator fokus yang berpindah saat tombol Tab ditekan. Karena itu indikator fokus bukan dekorasi, melainkan komponen aksesibilitas inti — dan karena banyak reset CSS menghapus outline bawaan browser, merancang ulang indikator tersebut menjadi tugas wajib setiap stylesheet. Pada Chapter ini kita memakai tiga pseudo-class fokus, lalu membangun outline kustom dengan outline-offset.

Tiga Pseudo-class Fokus #

CSS menyediakan tiga pseudo-class dengan tugas yang saling melengkapi (dasar-dasar pseudo-class dibahas pada Chapter Pseudo-classes ):

Pseudo-classCocok ketikaKhas digunakan untuk
:focuselemen difokuskan, apa pun penyebabnyakeadaan fokus pada umumnya
:focus-visiblebrowser menilai fokus harus terlihat (umumnya fokus keyboard)indikator untuk pengguna keyboard
:focus-withinelemen itu sendiri atau salah satu keturunannya difokuskanmenyorot kartu atau grup form

:focus-visible adalah Baseline dan menjadi pilihan modern untuk indikator: klik mouse pada tombol biasanya tidak menampilkannya, sedangkan tekanan Tab selalu menampilkannya — sehingga pengguna mouse tidak melihat cincin yang tidak diperlukan, dan pengguna keyboard tidak kehilangan arah. Pada elemen isian teks, kedua cara memicu :focus-visible karena kursor teks memang harus terlihat. Sementara itu, :focus-within menyorot pembungkus: kartu yang berisi input fokus ikut mendapat latar berbeda.

Outline Kustom dan outline-offset #

Indikator fokus paling aman dibangun dari outline karena outline digambar di luar kotak tanpa mengubah layout — berbeda dari border yang menggeser elemen di sekitarnya (perbedaan lengkapnya ada pada Chapter Outlines ):

css
.input-fokus:focus-visible {
  outline: 3px solid rgb(37, 99, 235);
  outline-offset: 2px;
}

.form-grup:focus-within {
  border-color: rgb(37, 99, 235);
  background-color: rgb(239, 246, 255);
}

.contoh-outline {
  width: 280px;
  padding: 10px 12px;
  border: 2px solid rgb(203, 213, 225);
  outline: 3px solid rgb(37, 99, 235);
  outline-offset: 2px;
}

Mari kita telaah aturan-aturan tersebut:

  1. Baris 1–4 (:focus-visible): outline biru setebal 3px hanya muncul saat browser menilai indikator fokus perlu terlihat — umumnya setelah navigasi keyboard.
  2. Baris 3 (outline-offset: 2px): memberi celah 2px antara tepi elemen dan garis outline, sehingga cincin tidak menempel pada border input.
  3. Baris 6–9 (:focus-within): bila salah satu anak .form-grup difokuskan, border pembungkus berubah biru dan latarnya menjadi biru sangat muda — umpan balik konteks tanpa JavaScript.
  4. Baris 11–16 (.contoh-outline): elemen pembanding dengan outline yang selalu aktif, bernilai identik dengan aturan :focus-visible di atas.

Hasil di Browser:

text
Elemen pembanding menampilkan outline 3px solid rgb(37, 99, 235)
dengan outline-offset 2px — nilai yang sama dengan aturan
:focus-visible pada input.
Grup form dalam keadaan biasa berlatar rgb(255, 255, 255); keadaan
:focus-within (latar rgb(239, 246, 255)) baru aktif saat anaknya difokuskan.

Praktik yang Menjaga Navigasi Keyboard #

Tiga kebiasaan menjaga indikator fokus tetap berfungsi. Pertama, jangan menulis outline: none atau outline: 0 tanpa pengganti — pengguna keyboard kehilangan satu-satunya penunjuk posisi. Kedua, bila memakai :focus-visible untuk indikator utama, jangan serentak memakai :focus yang menghapusnya; pilih satu strategi di seluruh halaman. Ketiga, berikan kontras yang cukup: outline 2–3px dengan warna berbeda dari latar lebih baik daripada bayangan tipis yang hampir tak terlihat. Untuk keadaan khusus seperti elemen fokus di dalam kartu gelap, outline-color dapat diubah per konteks tanpa menuliskan ulang seluruh shorthand.

Saat mengembangkan, DevTools membantu memeriksa keadaan fokus tanpa menekan Tab: pilih elemen di panel Elements, lalu paksa keadaannya lewat menu Force state (:focus dan :focus-visible tersedia di sana). Dengan begitu desain tiap keadaan dapat disempurnakan cepat, sementara pengujian akhir tetap dilakukan dengan keyboard sungguhan untuk memastikan urutan Tab masuk akal — fokus berpindah mengikuti urutan visual, bukan melompat ke elemen yang jauh di belakang.