Setelah kita belajar berbagai jenis input dan tombol, sekarang saatnya mengenal atribut-atribut penting yang membuat form lebih ramah pengguna dan profesional. Atribut-atribut ini akan membantu pengguna mengisi form dengan benar dan mencegah kesalahan.
Ringkasan Keempat Atribut
| Atribut | Fungsi | Pengguna Bisa Mengubah? | Data Terkirim ke Server? |
|---|---|---|---|
placeholder |
Menampilkan teks contoh di dalam input | Ya (teks placeholder hilang saat diketik) | Tidak (hanya contoh visual) |
required |
Memastikan field harus diisi sebelum submit | Ya | Ya (jika diisi) |
readonly |
Input hanya bisa dibaca (tidak bisa diubah) | Tidak | Ya (nilai tetap terkirim) |
disabled |
Input dinonaktifkan sepenuhnya | Tidak | Tidak (tidak terkirim) |
readonly→ data tetap terkirim, tapi tidak bisa diubahdisabled→ data TIDAK terkirim, dan tidak bisa diubahplaceholder→ hanya contoh visual, tidak mempengaruhi datarequired→ validasi wajib isi sebelum submit
1. Atribut placeholder - Teks Contoh
placeholder menampilkan teks contoh di dalam input yang hilang otomatis saat pengguna mulai mengetik. Sangat membantu untuk memberi petunjuk format input.
Contoh Dasar:
<input type="text" name="nama" placeholder="Masukkan nama lengkap"> <input type="email" name="email" placeholder="contoh@email.com"> <input type="tel" name="telpon" placeholder="08xx-xxxx-xxxx">
Contoh langsung:
Teks abu-abu di dalam input adalah placeholder — akan hilang saat kamu mulai mengetik
Placeholder untuk Textarea:
<textarea name="pesan" rows="4" placeholder="Tulis pesan Anda di sini..."></textarea>
- Jangan gunakan placeholder sebagai pengganti label — buruk untuk aksesibilitas!
- Placeholder yang baik:
"contoh@email.com"atau"DD/MM/YYYY" - Placeholder yang buruk:
"Isi di sini"(terlalu umum) - Gunakan warna teks placeholder yang kontras tapi tidak terlalu mencolok (biasanya abu-abu)
2. Atribut required - Wajib Diisi
required memastikan bahwa field harus diisi sebelum form bisa di-submit. Browser akan menampilkan pesan peringatan otomatis jika field kosong.
Contoh Dasar:
<input type="text" name="nama" required> <input type="email" name="email" required> <input type="number" name="umur" required>
Contoh langsung (coba submit tanpa mengisi):
Coba klik submit tanpa mengisi nama atau email — browser akan mencegah submit dan menampilkan peringatan!
Required pada Radio Button dan Checkbox:
<!-- Radio button: minimal satu dipilih --> <input type="radio" name="jenis_kelamin" value="laki" required> Laki-laki <input type="radio" name="jenis_kelamin" value="perempuan"> Perempuan <!-- Checkbox: harus dicentang (biasanya untuk setuju syarat) --> <input type="checkbox" name="setuju" required> Saya setuju dengan syarat & ketentuan
3. Atribut readonly - Hanya Baca
readonly membuat input tidak bisa diubah oleh pengguna, tetapi nilainya tetap terkirim ke server. Cocok untuk data yang sudah ditentukan sistem (seperti ID, username yang sudah terisi otomatis).
Contoh Dasar:
<input type="text" name="username" value="johndoe123" readonly> <input type="text" name="email" value="john@example.com" readonly>
Contoh langsung (coba edit — tidak bisa!):
Field dengan readonly memiliki latar abu-abu dan tidak bisa diedit, tapi nilainya tetap akan terkirim saat form di-submit
Readonly pada Textarea:
<textarea name="terms" rows="5" readonly> Syarat dan ketentuan aplikasi... </textarea>
- ID atau kode unik yang ditentukan sistem (tidak boleh diubah)
- Username yang sudah terisi otomatis dari email
- Data yang diambil dari database (sebagai konfirmasi)
- Syarat dan ketentuan yang hanya bisa dibaca
- Nilai perhitungan otomatis (total harga, dll)
4. Atribut disabled - Dinonaktifkan
disabled membuat input tidak bisa diubah dan nilainya TIDAK terkirim ke server. Cocok untuk opsi yang tidak tersedia atau sementara tidak aktif.
Contoh Dasar:
<input type="text" name="kode_voucher" value="DISKON50" disabled>
<select name="metode_pengiriman" disabled>
<option>Reguler (sedang tidak tersedia)</option>
</select>
Contoh langsung (coba interaksi — semua disabled):
Field dengan disabled memiliki tampilan redup (opacity) dan tidak bisa diinteraksi. Nilainya TIDAK akan terkirim ke server.
Disabled pada Tombol:
<button type="submit" disabled>Submit (Tidak Aktif)</button>
Tombol disabled tidak bisa diklik dan tampil redup
| readonly | Bisa di-focus / di-tab | Data terkirim ke server | Tampilan normal |
| disabled | Tidak bisa di-focus | Data TIDAK terkirim | Tampilan redup |
Studi Kasus: Form Profil dengan Semua Atribut
Berikut form lengkap yang menggabungkan placeholder, required, readonly, dan disabled:
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8">
<title>Form Profil - Pengaturan Akun</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: #f0f4f8;
padding: 40px 20px;
}
.profile-card {
max-width: 650px;
margin: 0 auto;
background: white;
border-radius: 20px;
box-shadow: 0 20px 40px rgba(0,0,0,0.1);
overflow: hidden;
}
.header {
background: linear-gradient(135deg, #3b82f6 0%, #1e40af 100%);
color: white;
padding: 25px 30px;
}
.header h1 {
font-size: 24px;
margin-bottom: 5px;
}
.header p {
opacity: 0.9;
font-size: 14px;
}
form {
padding: 30px;
}
.form-group {
margin-bottom: 20px;
}
label {
display: block;
margin-bottom: 8px;
font-weight: 600;
color: #333;
}
.required-star {
color: #ef4444;
}
.hint {
font-size: 12px;
color: #666;
margin-top: 5px;
}
input, select, textarea {
width: 100%;
padding: 12px;
border: 2px solid #e0e0e0;
border-radius: 10px;
font-size: 14px;
transition: all 0.3s;
font-family: inherit;
}
input:focus, select:focus, textarea:focus {
outline: none;
border-color: #3b82f6;
box-shadow: 0 0 0 3px rgba(59,130,246,0.1);
}
input:read-only, input:disabled, select:disabled, textarea:read-only {
background: #f5f5f5;
cursor: not-allowed;
}
input:disabled, select:disabled {
opacity: 0.6;
}
.row-2 {
display: flex;
gap: 20px;
}
.row-2 .form-group {
flex: 1;
}
.checkbox-group {
display: flex;
align-items: center;
gap: 10px;
}
.checkbox-group input {
width: auto;
}
.checkbox-group label {
margin-bottom: 0;
font-weight: normal;
}
.button-group {
display: flex;
gap: 15px;
margin-top: 25px;
}
.btn-submit {
background: #3b82f6;
color: white;
border: none;
padding: 12px 24px;
border-radius: 10px;
font-size: 16px;
font-weight: bold;
cursor: pointer;
flex: 1;
transition: transform 0.2s;
}
.btn-submit:hover {
transform: translateY(-2px);
background: #2563eb;
}
.btn-reset {
background: #ef4444;
color: white;
border: none;
padding: 12px 24px;
border-radius: 10px;
font-size: 16px;
font-weight: bold;
cursor: pointer;
flex: 1;
transition: transform 0.2s;
}
.btn-reset:hover {
transform: translateY(-2px);
background: #dc2626;
}
.info-box {
background: #f8f9fa;
padding: 15px;
border-radius: 10px;
margin-top: 20px;
font-size: 13px;
border-left: 4px solid #3b82f6;
}
.info-box ul {
margin-left: 20px;
margin-top: 8px;
}
hr {
margin: 20px 0;
border: none;
border-top: 1px solid #eee;
}
.badge {
display: inline-block;
background: #e5e7eb;
padding: 2px 8px;
border-radius: 12px;
font-size: 10px;
font-weight: normal;
margin-left: 8px;
color: #4b5563;
}
</style>
</head>
<body>
<div class="profile-card">
<div class="header">
<h1>Pengaturan Profil</h1>
<p>Kelola informasi akun Anda</p>
</div>
<form action="#" method="POST" id="profileForm">
<div class="row-2">
<div class="form-group">
<label>User ID <span class="badge">readonly</span></label>
<input type="text" name="user_id" value="USER-2024-001" readonly>
<div class="hint">ID tidak bisa diubah, otomatis dari sistem</div>
</div>
<div class="form-group">
<label>Status Akun <span class="badge">disabled</span></label>
<select name="status" disabled>
<option>Premium (Aktif)</option>
<option>Basic</option>
</select>
<div class="hint">Upgrade status sedang dalam proses</div>
</div>
</div>
<div class="form-group">
<label>Nama Lengkap <span class="required-star">*</span> <span class="badge">required</span></label>
<input type="text" name="fullname" placeholder="Contoh: Ahmad Fauzan" required>
<div class="hint">Masukkan nama sesuai KTP</div>
</div>
<div class="row-2">
<div class="form-group">
<label>Email <span class="required-star">*</span> <span class="badge">required</span></label>
<input type="email" name="email" placeholder="contoh@email.com" required>
</div>
<div class="form-group">
<label>Nomor Telepon <span class="badge">placeholder</span></label>
<input type="tel" name="phone" placeholder="08xx-xxxx-xxxx">
</div>
</div>
<div class="form-group">
<label>Alamat Lengkap <span class="badge">placeholder</span></label>
<textarea name="address" rows="3" placeholder="Jl. Contoh No. 123, RT/RW, Kelurahan, Kecamatan, Kota"></textarea>
</div>
<div class="form-group">
<label>Kode Voucher <span class="badge">disabled</span></label>
<input type="text" name="voucher" value="WELCOME50" disabled>
<div class="hint">Voucher sudah digunakan atau expired</div>
</div>
<div class="form-group">
<div class="checkbox-group">
<input type="checkbox" name="agreement" id="agreement" required>
<label for="agreement">Saya menyetujui syarat dan ketentuan yang berlaku <span class="required-star">*</span> <span class="badge">required</span></label>
</div>
</div>
<div class="button-group">
<button type="submit" class="btn-submit">
Simpan Perubahan
</button>
<button type="reset" class="btn-reset">
Reset Form
</button>
</div>
<div class="info-box">
Informasi Atribut yang Digunakan:
<ul>
<li><strong>placeholder</strong> → Nama, Email, Telepon, Alamat (memberi contoh format)</li>
<li><strong>required</strong> → Nama, Email, Setuju Syarat (wajib diisi)</li>
<li><strong>readonly</strong> → User ID (tidak bisa diubah, tapi tetap terkirim)</li>
<li><strong>disabled</strong> → Status Akun, Kode Voucher (tidak aktif, data tidak terkirim)</li>
</ul>
</div>
</form>
</div>
<script>
document.getElementById('profileForm').addEventListener('submit', function(e) {
e.preventDefault();
alert('Profil berhasil disimpan! (Contoh - data tidak benar-benar dikirim ke server)');
});
document.getElementById('profileForm').addEventListener('reset', function() {
alert('Form telah direset! Field yang readonly/disabled akan kembali ke nilai default.');
});
</script>
</body>
</html>
Tabel Perbandingan Lengkap
| Atribut | Bisa Diedit? | Bisa Di-focus? | Data Terkirim? | Tampilan Default |
|---|---|---|---|---|
| placeholder | Ya | Ya | Ya (nilai input) | Teks abu-abu di dalam input |
| required | Ya | Ya | Ya (jika diisi) | Validasi browser otomatis |
| readonly | Tidak | Ya | Ya | Normal (biasanya background abu-abu) |
| disabled | Tidak | Tidak | Tidak | Redup (opacity rendah) |
Kesalahan Umum Pemula
- Menggunakan
placeholdersebagai pengganti<label>→ Buruk untuk aksesibilitas (screen reader tidak membaca placeholder) - Lupa menambahkan
requiredpada radio button group → Cukup tambahkanrequireddi salah satu radio button dalam grup - Menggunakan
disabledketika seharusnyareadonly→ Data tidak terkirim! Jika data perlu tetap dikirim, gunakanreadonly - Menggunakan
readonlypada checkbox atau radio button → Tidak berfungsi dengan baik, gunakandisabledatau atur dengan JavaScript - Placeholder terlalu panjang → Bisa memotong dan tidak terbaca. Placeholder yang baik maksimal 30-40 karakter
- Jika form tidak bisa submit padahal semua field sudah diisi → cek apakah ada checkbox dengan
requiredyang belum dicentang - Jika data tidak terkirim ke server → cek apakah field tidak sengaja diberi
disabled(ganti denganreadonlyjika perlu tetap terkirim) - Jika placeholder tidak muncul → cek apakah ada nilai
valueyang sudah terisi (placeholder tidak muncul jika value ada)
Latihan Singkat
- Buat file HTML baru dengan judul "Form Pemesanan Tiket"
- Buat form dengan field-field berikut:
- Kode Booking (readonly, nilai default: "TICKET-2024-001")
- Nama Pemesan (required, placeholder: "Masukkan nama lengkap")
- Email (required, placeholder: "contoh@email.com")
- Jenis Tiket (select dengan opsi: Regular, VIP, VVIP — disable opsi VVIP karena sold out)
- Syarat & Ketentuan (textarea readonly dengan teks contoh)
- Checkbox "Saya setuju" (required)
- Buat tombol submit dengan alert konfirmasi
- Simpan dan buka di browser, coba fungsi setiap atribut
Intisari Hari Ini
placeholder→ teks contoh di dalam input (hilang saat diketik)required→ field wajib diisi (validasi browser otomatis)readonly→ hanya baca, tidak bisa diubah, data tetap terkirimdisabled→ dinonaktifkan, tidak bisa diubah, data TIDAK terkirim- Jangan gunakan placeholder sebagai pengganti label (buruk untuk aksesibilitas)
- Gunakan readonly untuk data otomatis yang perlu dikirim, disabled untuk opsi yang tidak tersedia
- placeholder → untuk field alamat, nomor telepon, kode pos (beri contoh format yang benar)
- required → semua field penting (nama, alamat, telepon, metode pembayaran)
- readonly → untuk ID transaksi (otomatis dari sistem) dan total harga (hasil perhitungan)
- disabled → untuk opsi pengiriman yang sedang tidak tersedia (misal: "Reguler - Sedang Penuh")
- Tambahkan checkbox "Setuju dengan syarat & ketentuan" dengan required
- Gunakan CSS yang menarik dan buat kotak penjelasan di bagian bawah form yang menjelaskan penggunaan setiap atribut
- Buat simulasi perhitungan total harga sederhana dengan JavaScript (type="button")
Artikel Sebelumnya: HTML Dasar #14 - Tombol (button) dan Submit
Artikel Selanjutnya: HTML Dasar #16 - Perbedaan div dan span (Block vs Inline Element)
