Formulir HTML memiliki sistem validasi bawaan: atribut seperti required, type="email", dan minlength membuat browser menilai sendiri apakah isian memenuhi syarat. CSS dapat membaca hasil penilaian tersebut lewat pseudo-class :valid dan :invalid — tanpa JavaScript. Namun ada jebakan pengalaman pengguna yang wajib dipahami sejak awal: :invalid aktif sejak halaman dimuat, sehingga input wajib yang belum diisi apa pun langsung tampil merah sebelum pengguna sempat mengetik. Pada Chapter ini kita menata kedua pseudo-class tersebut, lalu memperkenalkan :user-valid dan :user-invalid yang menunggu pengguna berinteraksi terlebih dahulu.
:valid dan :invalid Aktif Sejak Awal #
Pseudo-class ini mengikuti status validasi elemen secara langsung:
.input {
font: inherit;
padding: 8px 12px;
border: 2px solid rgb(203, 213, 225);
border-radius: 8px;
}
.input:invalid { border-color: rgb(220, 38, 38); }
.input:valid { border-color: rgb(22, 163, 74); }Mari kita telaah perilakunya:
- Baris 1–6 (
.input): gaya dasar input dengan border netral — seluruh status nantinya hanya mengganti warna border, bukan menambah properti baru. - Baris 8 (
.input:invalid): bila elemen gagal validasi, border berubah merah. Untuk<input required>yang kosong, kondisi ini telah terpenuhi pada detik halaman dibuka — isi kosong gagal syaratrequired. - Baris 9 (
.input:valid): bila isian memenuhi semua syarat — misalnyatype="email"berisi[email protected]— border berubah hijau.
Hasil di Browser:
Input email wajib yang kosong: border merah rgb(220, 38, 38)
sejak halaman dimuat — :invalid aktif tanpa interaksi.
Input email berisi [email protected]: border hijau rgb(22, 163, 74).
Input yang dinonaktifkan: latar rgb(241, 245, 249) dan teks
rgb(148, 163, 184).Ketiga nilai itu diprobe otomatis pada demo — termasuk border merah pada input yang belum pernah disentuh, bukti nyata perilaku “merah sejak awal” di atas.
:user-valid dan :user-invalid yang Menunggu Interaksi #
:user-invalid
dan pasangannya :user-valid memperbaiki masalah tersebut: keduanya baru cocok setelah pengguna berinteraksi dengan kontrol — mengetik lalu membuatnya tidak sah, atau mengosongkan kembali field yang telah diisi. Fitur ini merupakan Baseline sejak 2024. Strategi yang nyaman dipakai: biarkan :invalid untuk sinyal halus (misalnya warna teks hint), dan serahkan sinyal kuat seperti border merah mencolok kepada :user-invalid:
.input:user-invalid { border-color: rgb(147, 51, 234); }Pada demo, aturan ungu ini diletakkan setelah aturan merah — bila keduanya cocok, ungu menang karena urutan source. Namun probe menunjukkan border tetap merah: pada keadaan awal tanpa interaksi, :user-invalid belum cocok, sehingga aturan ungu tidak berlaku. Inilah perbedaan keduanya dalam satu gambar: :invalid menilai data, :user-invalid menilai data dan pengalaman pengguna.
:required, :optional, dan :disabled #
Tiga pseudo-class lain melengkapi kotak peralatan validasi. :required dan :optional membedakan field wajib dari bebas — pasangan yang tepat untuk menambah tanda bintang atau label “opsional” tanpa class tambahan. Sementara itu, :disabled menata elemen dengan atribut disabled: kontrol tersebut tidak dapat diedit, tidak ikut dikirim saat form disubmit, dan dilewati navigasi Tab. Gaya khasnya adalah latar dan teks yang redup — bukan sekadar opacity, karena teks redup eksplisit lebih dapat diprediksi di seluruh browser:
.input:disabled {
background-color: rgb(241, 245, 249);
color: rgb(148, 163, 184);
}Dengan keenam pseudo-class di atas — :valid, :invalid, :user-valid, :user-invalid, :required, dan :disabled — status setiap kontrol dapat ditata murni lewat CSS, dan JavaScript cukup menangani pesan galat yang lebih kompleks.