Ada dua cara mengunci kolom form, dan keduanya sering ditukar. Attribute disabled mematikan kontrol sepenuhnya — tidak bisa diedit, tidak bisa difokus, dan nilainya tidak ikut terkirim. Attribute readonly hanya mengunci penyuntingan — nilainya tetap terlihat, tetap terkirim, dan kolomnya masih bisa difokus. Karena perilaku keduanya berbeda, tampilannya juga sebaiknya dibedakan agar pengguna bisa menebak apa yang bisa mereka lakukan. Pada chapter ini kita menata keduanya secara sadar, lalu mengenal trik fieldset disabled yang mengunci satu grup sekaligus.
Dua Kunci yang Berbeda #
| Aspek | disabled | readonly |
|---|---|---|
| Bisa diedit | Tidak | Tidak |
| Bisa difokus dan diklik | Tidak | Ya |
| Nilai ikut disubmit | Tidak | Ya |
| Bisa diberi event klik | Tidak | Ya |
| Berlaku pada | Hampir semua kontrol form | Input teks, textarea, dan select |
Perbedaan paling menentukan ada pada baris submit: kontrol yang disabled dianggap tidak ada saat form dikirim, sedangkan nilai readonly tetap tiba di server. Karena itu pilihlah berdasarkan maksud — readonly untuk data yang ditampilkan tapi tidak boleh diubah pengguna, disabled untuk kontrol yang memang sedang tidak berlaku.
CSS membaca keadaan ini lewat pseudo-class :disabled yang sudah dibahas pada section Pseudo-classes, plus attribute selector [readonly] dari section Selectors. Ada pula :read-only sebagai pasangan pseudo-class-nya, yang mencocokkan kontrol yang tidak bisa disunting — termasuk yang readonly:
.kolom-kode:disabled { ... }
.kolom-kode[readonly] { ... }Menata Keduanya secara Berbeda #
Konvensi visual yang dipahami luas: kontrol disabled tampil pudar dan seperti tidak tertarik untuk diinteraksi, sedangkan kolom readonly tetap terbaca jelas karena isinya adalah informasi yang perlu dilihat pengguna:
.kolom-form:disabled {
opacity: 0.55;
background-color: #eef1ef;
border-color: #d9d2c0;
cursor: not-allowed;
}
.kolom-form[readonly] {
background-color: #f4fbf7;
border-style: solid;
color: #14503a;
cursor: default;
}Klik kedua kolom pada demo berikut — hanya salah satunya yang masih bisa menerima fokus dan disunting:
Beberapa keputusan di dalam resep ini perlu dipahami:
opacity: 0.55: memudarkan seluruh kontrol sekaligus; konvensi pudar inilah isyarat paling dikenali untuk “tidak bisa dipakai”.cursor: not-allowed: hanya terasa pada kontroldisabled; kolom readonly lebih jujur memakaicursor: defaultkarena klik di sana tetap sah — fokusnya pindah, teksnya bisa diseleksi dan disalin.- Warna yang tetap kontras: kolom readonly tetap perlu terbaca nyaman, jadi teksnya tidak dipudarkan; yang berubah hanya latar dan warna tepinya.
Pseudo-class :enabled adalah kebalikan :disabled, tetapi jarang dibutuhkan: kontrol yang tidak cocok dengan :disabled memang sudah tampil normal tanpa aturan apa pun. Yang lebih sering terlewat adalah memastikan state ini terasa konsisten pada semua jenis kontrol — select yang disabled tetap menampilkan pilihan terpilihnya dalam keadaan pudar, dan textarea yang readonly tetap bisa di-scroll isinya. Uji keduanya dengan keyboard: kontrol disabled harus terlewat dalam navigasi Tab, sedangkan kolom readonly justru tetap menerima fokus — dua sinyal perilaku yang seharusnya sejalan dengan tampilannya.
fieldset disabled: Kunci Satu Grup Sekaligus #
Attribute disabled juga sah pada <fieldset>, dan efeknya merambat ke seluruh kontrol di dalamnya — input, select, sampai tombol submit yang ikut terkunci. Ini cara paling hemat untuk kondisi seperti “form belum aktif sampai syarat dipenuhi”:
<fieldset class="grup-alamat" disabled>
<legend>Alamat pengiriman</legend>
<label for="demo-jalan">Jalan</label>
<input id="demo-jalan" type="text">
<label for="demo-kota-alamat">Kota</label>
<input id="demo-kota-alamat" type="text">
</fieldset>.grup-alamat:disabled {
opacity: 0.55;
}
.grup-alamat:disabled legend {
color: #8a948f;
}Melepas satu attribute disabled di fieldset akan menghidupkan kembali seluruh grup.
Pola ini paling berguna dikombinasikan dengan checkbox persetujuan: selama checkbox induk belum tercentang, fieldset tetap disabled, dan JavaScript hanya perlu mengganti satu attribute untuk membukanya. Untuk chapter ini, cukup sisi CSS-nya yang kita pegang.
Ringkasan #
disabled dan readonly mengunci hal yang berbeda — interaksi sekaligus pengiriman nilai, versus penyuntingan saja — dan tampilannya perlu dibedakan dengan sengaja: pudar dan kursor larangan untuk yang disabled, kontras tetap terjaga untuk yang readonly. Attribute selector [readonly] dan pseudo-class :disabled membuat keduanya mudah ditata, sementara fieldset disabled memberi cara mengunci satu grup kontrol dalam satu langkah. Dengan seluruh state form sudah terbahas, chapter berikutnya naik satu tingkat: menyusun form itu sendiri menjadi layout yang rapi.