Tutorial CSS / Status Formulir CSS: Fokus, Validasi, disabled, dan readonly
CSS dapat memberi gaya pada fokus, validitas, dan kontrol form yang dinonaktifkan atau hanya-baca, tetapi HTML menetapkan label, batasan, dan perilaku pengirimannya. :invalid dapat mencocokkan sebelum interaksi, sementara :user-invalid membantu menunda penerapan gaya kesalahan hingga browser menganggapnya tepat.
Hubungkan label dan instruksi dengan kontrol
Jika atribut for pada label sama dengan atribut id pada kolom input, nama item dan kolom input akan terhubung. Placeholder akan hilang begitu Anda mulai mengetik, sehingga mereka tidak menggantikan nama atau kondisi penting. Untuk penjelasan tambahan, biarkan kalimat tetap terlihat dan tentukan ID dari kalimat tersebut di aria-describedby.
<label for="email">Email address (required)</label>
<input id="email" name="email" type="email" required
placeholder="name@example.com" aria-describedby="email-help">
<p id="email-help">Enter name@example.com in the same format.</p>
Kode parsial di atas secara singkat mewakili bagian email dari contoh lengkap di bawah ini. id mengidentifikasi objek dalam dokumen, dan name adalah nama item dalam data yang dikirimkan. Jika name tidak ada, itu tidak akan termasuk dalam pengiriman normal, meskipun Anda dapat mengetiknya di layar. Untuk susunan label dan deskripsi, lihat panduan label form W3C dan panduan input form .
Atur ukuran kontrol untuk layar sempit dan teks besar
Jika Anda hanya mengandalkan lebar asli dari kolom input, itu mungkin melebihi layar sempit ketika ukuran font ditingkatkan. Tetapkan lebar maksimum formulir dan gunakan width: 100% dan box-sizing: border-box bersama-sama di kolom input. Ini akan memastikan bahwa batas dan padding juga termasuk dalam lebar yang ditentukan.
*, *::before, *::after { box-sizing: border-box; }
form { max-width: 28rem; }
input { width: 100%; min-width: 0; padding: .65rem; font: inherit; }
Aturan ini termasuk dalam bagian gaya dari seluruh contoh. font: inherit memungkinkan kolom input dan tombol mengikuti font, ukuran, dan tinggi baris dari teks, dan min-width membantu mengurangi ukuran minimum yang mencegah penyusutan meskipun memasukkan kolom input ke dalam Flexbox/Grid. Tinggi tetap tidak digunakan agar item di bawahnya bergerak ke bawah secara alami meskipun deskripsi ditingkatkan atau huruf diperbesar.
Pisahkan status fokus dan kesalahan validasi
:focus mencocokkan elemen yang saat ini memiliki fokus, dan :focus-visible mencocokkan jika browser menentukan bahwa perlu menampilkan fokus. Ini terutama ditampilkan selama navigasi dengan keyboard, tetapi juga dapat ditampilkan dengan mengklik menggunakan mouse di kolom input teks, jadi tidak seharusnya dipahami sebagai "hanya berlaku untuk keyboard." Penjelasan penentuan focus-visible di MDN. Untuk menerapkan indikasi fokus secara konsisten pada tautan juga, bandingkan CSS Link States dan Visible Keyboard Focus.
Fokus menunjukkan item yang sedang Anda manipulasi, dan kesalahan menunjukkan item yang tidak memenuhi kondisi input. Karena kedua status dapat hadir pada saat yang sama, seluruh contoh menunjukkan fokus dengan garis biru dan kesalahan dengan batas merah tua serta pernyataan kesalahan. Sisakan sedikit ruang di sekitar garis untuk menghindari pemotongan, dan jangan menghapus garis serta tidak menyediakan indikator fokus lain.
:invalid cocok jika nilai saat ini tidak valid, sehingga bidang input yang diperlukan yang kosong juga cocok sejak awal. :user-invalid cocok ketika browser akan menampilkan kondisi kesalahan setelah interaksi pengguna. Waktu munculnya keadaan tersebut, misalnya setelah menyunting atau mencoba mengirim formulir, bergantung pada perilaku browser. Dalam latihan ini, periksa kesalahan dengan menekan tombol Check submitted fields. Penjelasan user-invalid di MDN.
Jika Anda perlu mempertimbangkan target dukungan yang lebih lama, Anda harus memeriksa apakah selector didukung dan merancang alur verifikasi terpisah. Bahkan jika dekorasi kesalahan tidak muncul karena selector tidak didukung, ini tidak berarti bahwa pemeriksaan required dan formatting pada HTML hilang. Pilih warna fokus yang cukup berbeda dari latar belakang sebenarnya, dan juga periksa kondisi penerapan W3C Non-Text Contrast Guide.
Bandingkan required, valid, disabled, dan readonly
| situasi | makna | Fokus dan pengiriman umum |
|---|---|---|
required |
Pengguna harus memasukkan nilai | Dapat difokuskan jika item aktif; Nilai kosong akan divalidasi saat pengiriman |
:valid·:invalid |
Apakah kondisi validasi HTML terpenuhi | Hasil verifikasi ditentukan secara independen dari bentuk batas |
disabled |
Saat ini tidak tersedia | Biasanya dikecualikan dari navigasi tab dan pengiriman |
readonly |
Tidak dapat mengubah nilai seperti input teks yang didukung | Dapat difokuskan dan dipilih; Jika nama ada, sertakan dalam pengiriman |
readonly didukung oleh kontrol tertentu yang mirip teks dan bukan cara umum untuk membuat elemen select menjadi hanya-baca. Kontrol hanya-baca yang didukung dikecualikan dari validasi batasan, sementara kontrol bernama masih dapat memasukkan data formulir yang dikirim. Bedakan perilaku ini dari kontrol yang dinonaktifkan. Lihat Standar HTML: menyusun daftar data formulir, MDN: atribut readonly.
Bidang email ini menunjukkan format seperti name@example.com. Lulus pemeriksaan validitasnya tidak mengonfirmasi bahwa akun tersebut ada atau dapat menerima email. Validasi HTML type="email" tidak menerima setiap format alamat terinternasionalisasi; bagian lokal non-ASCII tidak disajikan di sini sebagai input yang dijamin valid. Untuk detail lebih lanjut, lihat Standar HTML: ketentuan input email.
Jalankan contoh dan periksa kolom yang dikirim
Simpan kode berikut sebagai form-states.html dalam format UTF-8 dan buka di peramban Anda. HTML dan CSS menentukan status formulir. Potongan kecil JavaScript di bagian akhir adalah kode tambahan untuk menangkap pengiriman yang sah dan menampilkan daftar data di layar, tanpa mengirimkannya ke server atau melakukan pemeriksaan input tambahan. Jika JavaScript dimatikan, fungsi output hasil tidak akan bekerja.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Comparing form states and submitted fields</title>
<style>
*, *::before, *::after { box-sizing: border-box; }
body { margin: 0; padding: 1rem; color: #183044; font-family: sans-serif; line-height: 1.6; }
main { max-width: 46rem; margin-inline: auto; }
h1 { font-size: 1.5rem; } h2 { font-size: 1.2rem; }
button, input { font: inherit; }
button { cursor: pointer; }
:focus-visible { outline: 3px solid #164f73; outline-offset: 3px; }
form { max-width: 28rem; }
.field { margin-block: 1.25rem; }
label { display: block; margin-bottom: .35rem; font-weight: 700; }
input { display: block; width: 100%; min-width: 0; padding: .65rem;
border: 2px solid #6d7e8b; border-radius: .3rem; background: white; color: #183044; }
input:required { border-inline-start-width: 4px; }
input:user-invalid { border-color: #9d2632; }
.help, .error { margin-block: .4rem 0; }
.error { display: none; color: #9d2632; }
input:user-invalid + .error { display: block; }
input[readonly] { background: #eef6fa; }
input:disabled { background: #eceff2; color: #465766; cursor: not-allowed; }
button { padding: .65rem 1rem; border: 1px solid #164f73; border-radius: .3rem;
background: #166b92; color: white; }
output { display: block; margin-block: 1rem; white-space: pre-wrap; overflow-wrap: anywhere; }
</style>
</head>
<body>
<main>
<h1>Check input states and submitted data</h1>
<form id="demo-form">
<div class="field">
<label for="email">Email address (required)</label>
<input id="email" name="email" type="email" autocomplete="email" required
placeholder="name@example.com" aria-describedby="email-help email-error">
<p id="email-error" class="error">Enter an email address in a format such as name@example.com; do not leave the field empty.</p>
<p id="email-help" class="help">This sample input checks the address format. It does not check whether the example address receives mail.</p>
</div>
<div class="field">
<label for="plan">Plan (read-only)</label>
<input id="plan" name="plan" type="text" value="Basic" readonly>
</div>
<div class="field">
<label for="coupon">Coupon (currently disabled)</label>
<input id="coupon" name="coupon" type="text" value="WELCOME" disabled>
</div>
<button type="submit">Check submitted fields</button>
</form>
<output id="result" for="email plan coupon" aria-live="polite"></output>
<script>
const form = document.getElementById("demo-form");
form.addEventListener("submit", (event) => {
event.preventDefault();
const entries = Array.from(new FormData(form).entries());
document.getElementById("result").textContent = JSON.stringify(entries, null, 2);
});
</script>
</main>
</body>
</html>
- Biarkan kolom email kosong lalu tekan Check submitted fields. Periksa peramban Anda untuk petunjuk input yang dibutuhkan dan pesan kesalahan.
- Masukkan
abcdi email dan kirim ulang. Daftar hasil baru seharusnya tidak ditampilkan karena kesalahan format. - Masukkan
name@example.comdan kirimkan. Hasilnya mencakup email dan plan bernilai Basic, sedangkan coupon bernilai WELCOME tidak disertakan karena disabled. - Gunakan tombol Tab untuk menavigasi dalam urutan Email → Plan → Check submitted fields. Kupon yang tidak aktif dilewati dari urutan tab normal, dan kolom Plan yang hanya-baca dapat menerima fokus.
- Dalam seluruh contoh, kita hanya menghapus atribut disabled dari kupon. Anda dapat fokus pada kupon dan menambahkan nilai ke daftar pengiriman Anda. Setelah konfirmasi, kembalikan atribut disabled.
- Hapus hanya atribut
readonlydari kolom Plan lalu coba menyunting nilainya. Setelah perbandingan, kembalikan nilainya ke “Basic” dan tambahkanreadonlylagi. - Kurangi lebar layar dan sesuaikan pengaturan pembesaran browser atau ukuran font. Periksa bahwa kolom input, garis fokus, dan kalimat kesalahan tidak terpotong atau tumpang tindih.
Pahami batasan CSS dan validasi browser
CSS bertanggung jawab untuk menampilkan status suatu item. Verifikasi browser dapat mengurangi kesalahan input pengguna, tetapi dapat dilewati dengan alat pengembang atau permintaan terpisah, jadi layanan sebenarnya harus memeriksa kembali nilai yang diperbolehkan, panjang, izin, dll. di server. Kalimat kesalahan secara khusus menjelaskan item bermasalah dan solusinya, dan alur terpisah untuk menjaga informasi input juga dirancang ketika terjadi kesalahan server.
Jika contoh berperilaku tidak seperti yang diharapkan, pertama periksa pasangan for/id pada label dan input, atribut name, required, jenis input, dan status nonaktif atau hanya-baca. Jika fokus tidak terlihat, periksa apakah aturan outline lain menimpanya. Kesalahan yang ditampilkan segera mungkin berasal dari :invalid. Jika pesan tetap tersembunyi setelah percobaan pengiriman, periksa dukungan :user-invalid dan Kombinator dan Kelas Semu CSS.




