Setiap kolom form yang kita tata membawa tanggung jawab baru: begitu tampilan bawaannya diganti, indikator fokus bawaannya juga ikut tergantikan oleh gaya kita. Untuk pengguna keyboard, indikator itu satu-satunya petunjuk posisi — tanpa ia, mengisi form dengan Tab terasa seperti berjalan dalam gelap. Untungnya dua pseudo-class yang sudah kita kenal pada section Pseudo-classes, :focus-visible dan :focus-within, memberi kita kendali yang tepat. Pada chapter ini kita terapkan keduanya pada form: ring yang konsisten untuk tiap kolom, dan sorotan pada wrapper field saat kolom di dalamnya menerima fokus.

:focus-visible pada Input Teks #

Browser menilai sendiri kapan indikator fokus perlu ditampilkan. Aturan praktisnya: fokus yang datang dari keyboard selalu ditandai, sedangkan klik mouse pada tombol biasanya tidak. Input teks adalah pengecualian yang menguntungkan: karena pengguna hampir pasti akan mengetik, input teks selalu cocok dengan :focus-visible, apa pun cara fokusnya — klik maupun Tab. Artinya kita tidak perlu trik apa pun; cukup satu aturan:

css
.kolom-form:focus-visible {
  outline: 2px solid #1f6f54;
  outline-offset: 2px;
}

Klik atau Tab ke dalam kolom berikut: ring outline hijau muncul apa pun cara fokusnya datang:

Untuk input teks, perilaku ini adalah default yang baik; kita cukup mengganti warna dan bentuknya agar menyatu dengan desain.

Ring Recipe: Outline atau Box-Shadow #

Dua property yang paling lazim untuk ring fokus punya karakter berbeda:

PropertyKarakterCatatan
outlineDigambar di luar kotak, tidak memengaruhi layoutIkut mengikuti border-radius pada browser modern; pilihan paling sederhana
box-shadow berbentuk ringDigambar mengelilingi kotak, menempel pada radius0 0 0 3px menghasilkan cincin pejal; bisa digabung dengan bayangan lain

Versi ring dengan box-shadow terlihat seperti ini:

css
.kolom-form:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px #9ed2b5;
}

Fokuskan juga kolom berikut yang memakai versi ring box-shadow:

Perhatikan pola yang dipakai: outline: none di sini sah karena langsung digantikan ring box-shadow yang jelas — larangan menghapus outline hanya berlaku tanpa pengganti. Sisi praktisnya: pilih satu resep untuk seluruh form dan gunakan konsisten. Outline lebih ringkas; ring box-shadow lebih menyatu dengan radius dan bisa ditumpuk dengan bayangan kartu.

:focus-within untuk Wrapper Field #

:focus-within mencocokkan elemen yang sedang memuat fokus di dalam dirinya. Pada form, ini membuka pola yang populer: bukan kolom yang disorot, melainkan wadahnya — card, baris form, atau container label. Pola ini menjadi fondasi highlight pada floating label dan form bertingkat:

css
.wadah-field {
  padding: 10px 14px;
  border: 1px solid #d9d2c0;
  border-radius: 12px;
  background-color: #fdfaf3;
}

.wadah-field:focus-within {
  border-color: #1f6f54;
  box-shadow: 0 0 0 3px #e4f1e9;
}

.wadah-field:focus-within .label-field {
  color: #14503a;
}

Pengguna melihat konteks “field mana yang sedang aktif”, bukan sekadar kotak yang aktif. Pola ini bekerja tanpa JavaScript karena :focus-within merambat dari anak ke induk secara otomatis. Untuk floating label — label yang mengecil dan naik ke tepi atas kolom saat kolom terisi — mekanisme yang sama yang menjadi pemicunya, ditambah selektor seperti :placeholder-shown yang dibahas pada chapter ::placeholder.

Label dan Input: Pasangan yang Tidak Boleh Terputus #

Ring fokus yang bagus tidak menggantikan tugas label. Recap singkat dari section Selectors dan pseudo-classes:

  • Hubungkan label dengan input lewat pasangan atribut for dan id, atau dengan membungkus input di dalam label.
  • Klik pada label memindahkan fokus ke input-nya — area klik ikut melebar secara gratis.
  • Ring fokus yang kita buat harus tetap berada dekat kolom yang terfokus; jangan menaruh ring pada elemen yang jauh dari input-nya.
html
<label for="demo-email">Email</label>
<input id="demo-email" type="email">

Hubungan for/id ini juga yang membuat pembaca layar menyebutkan nama field saat input menerima fokus. Ring yang indah tanpa label yang terhubung tetap meninggalkan pengguna tanpa konteks.

Ringkasan #

:focus-visible memberi indikator yang muncul tepat ketika dibutuhkan — dan untuk input teks, itu berarti selalu — sementara :focus-within mengangkat sorotan ke wadah field sehingga pengguna melihat konteksnya, bukan hanya kotaknya. Ring outline dan ring box-shadow adalah dua resep yang sah; yang penting satu pilihan dipakai konsisten dan tidak pernah menghapus outline tanpa pengganti. Chapter berikutnya memakai pola pseudo-class yang sama untuk keadaan yang lebih bernuansa: valid dan tidak valid pada kolom form.