Kenapa ini penting
Bayangkan kamu membangun rumah. Sebelum memikirkan cat dinding atau model sofa, kamu butuh pondasi, tiang, dan denah ruangan. HTML (HyperText Markup Language) adalah denah dan tiang itu. Browser seperti Chrome atau Firefox membaca file HTML, lalu menyusunnya menjadi pohon objek yang disebut DOM (Document Object Model). CSS menempel ke DOM itu, JavaScript memanipulasinya, dan mesin pencari seperti Google membacanya untuk memahami isi halaman.
Kalau struktur HTML kamu berantakan, misalnya tag tidak ditutup, meta viewport lupa dipasang, atau form tanpa atribut name, efeknya bisa macam-macam: tampilan di HP jadi mini seperti versi desktop yang diperkecil, data form tidak terkirim ke server, atau gambar tidak bisa dipahami oleh pengguna tunanetra. Modul ini membekali kamu dengan anatomi dokumen yang benar sejak baris pertama.
Konsep inti
Anatomi sebuah elemen
HTML tersusun dari elemen. Satu elemen biasanya terdiri dari tag pembuka, isi, dan tag penutup:
| Bagian | Contoh | Keterangan |
|---|---|---|
| Tag pembuka | <a href="/kontak"> |
Nama elemen plus atribut |
| Atribut | href="/kontak" |
Informasi tambahan, format nama="nilai" |
| Isi | Hubungi kami |
Teks atau elemen lain di dalamnya |
| Tag penutup | </a> |
Nama elemen dengan garis miring |
Ada juga void element (elemen kosong) yang tidak punya isi dan tidak punya tag penutup, misalnya <img>, <input>, <br>, <meta>, dan <link>.
Elemen bisa bersarang (nested) seperti kotak di dalam kotak. Aturannya: yang dibuka terakhir harus ditutup duluan. <p><strong>Halo</strong></p> benar, sedangkan <p><strong>Halo</p></strong> salah.
Kerangka dokumen
Setiap halaman HTML modern dimulai dengan kerangka yang sama:
<!DOCTYPE html>memberi tahu browser untuk memakai mode standar HTML5. Tanpa baris ini browser bisa masuk "quirks mode", yaitu mode kompatibilitas lama yang membuat perhitungan ukuran kotak jadi aneh.<html lang="id">adalah elemen akar. Atributlangmembantu screen reader memilih logat pengucapan dan membantu mesin pencari mengenali bahasa halaman.<head>berisi informasi tentang halaman yang tidak tampil langsung: judul tab, encoding karakter, deskripsi, file CSS.<body>berisi semua yang tampil ke pengunjung.
Tiga isi <head> yang wajib kamu hafal:
<meta charset="UTF-8">supaya huruf seperti é, emoji, atau aksara non-Latin tampil benar, bukan jadi simbol aneh.<meta name="viewport" content="width=device-width, initial-scale=1">supaya di HP lebar halaman mengikuti lebar layar. Tanpa ini, HP akan merender halaman seolah lebarnya sekitar 980px lalu mengecilkannya.<title>yang tampil di tab browser dan di hasil pencarian Google.
Elemen dasar teks
- Judul:
<h1>sampai<h6>. - Paragraf:
<p>. - Penekanan:
<strong>(penting, biasanya tebal) dan<em>(penekanan nada, biasanya miring). - Baris baru:
<br>, pakai seperlunya saja (misalnya untuk alamat atau puisi), jangan untuk memberi jarak antar paragraf. - Pembungkus generik:
<div>(blok) dan<span>(inline). Keduanya tidak punya makna; pakai kalau memang tidak ada elemen yang lebih cocok.
Link dan gambar
<a href="..."> membuat link. Nilai href bisa URL absolut (https://example.com), path relatif (about.html), anchor ke bagian halaman (#harga), email (mailto:halo@contoh.id), atau telepon (tel:+628123456789). Kalau link dibuka di tab baru dengan target="_blank", browser modern sudah otomatis menerapkan perilaku noopener, tetapi menulis rel="noopener noreferrer" secara eksplisit tetap kebiasaan yang aman.
<img src="..." alt="..."> menampilkan gambar. Atribut alt adalah teks pengganti yang dibaca screen reader dan muncul kalau gambar gagal dimuat. Tambahkan juga width dan height supaya browser bisa menyisakan ruang sebelum gambar selesai diunduh, sehingga halaman tidak "loncat" (dalam istilah performa disebut CLS, Cumulative Layout Shift). Untuk gambar di bawah layar pertama, loading="lazy" menunda unduhan sampai gambar hampir terlihat.
List dan tabel
<ul>untuk daftar tanpa urutan (bullet),<ol>untuk daftar berurutan (nomor); keduanya berisi<li>.<dl>,<dt>,<dd>untuk pasangan istilah dan definisi.
Tabel dipakai untuk data tabular (jadwal, harga, nilai), bukan untuk tata letak halaman. Strukturnya: <table> berisi <caption> (judul tabel), <thead> (baris judul), <tbody> (isi), dan opsional <tfoot>. Sel judul memakai <th scope="col"> atau <th scope="row">, sel biasa memakai <td>.
Form dan input types
Form adalah cara pengunjung mengirim data. Atribut penting:
action: ke URL mana data dikirim.method:get(data masuk ke URL, cocok untuk pencarian) ataupost(data di body request, cocok untuk login atau pendaftaran).- Setiap input butuh
name, karena itulah "kunci" data yang diterima server. Input tanpanametidak ikut terkirim. - Setiap input butuh
<label>yang terhubung lewat atributforyang sama denganidinput.
HTML5 menyediakan banyak type input yang otomatis memberi keyboard yang sesuai di HP dan validasi gratis:
| type | Kegunaan | Bonus dari browser |
|---|---|---|
text |
Teks bebas | - |
email |
Alamat email | Validasi format, keyboard ada "@" |
password |
Kata sandi | Karakter disamarkan |
number |
Angka | Tombol naik turun, min/max/step |
tel |
Nomor telepon | Keypad angka di HP |
date |
Tanggal | Date picker bawaan |
checkbox |
Pilihan ganda | Bisa centang beberapa |
radio |
Pilih satu | Dikelompokkan lewat name yang sama |
file |
Unggah berkas | accept membatasi jenis file |
range |
Slider | - |
Atribut validasi seperti required, minlength, maxlength, pattern, min, dan max membuat browser menolak pengiriman sebelum data valid. Ingat, validasi di browser hanya untuk kenyamanan pengguna; server tetap harus memvalidasi ulang karena siapa pun bisa mengirim request tanpa lewat form kamu.
Contoh kode
Simpan sebagai index.html, lalu buka di browser.
<!DOCTYPE html>
<html lang="id">
<head>
<!-- Encoding karakter: taruh paling atas di head -->
<meta charset="UTF-8">
<!-- Supaya tampilan di HP mengikuti lebar layar -->
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="Warung Kopi Senja, kopi susu gula aren di Bandung.">
<title>Warung Kopi Senja | Menu & Pemesanan</title>
</head>
<body>
<h1>Warung Kopi Senja</h1>
<p>Kopi susu gula aren <strong>tanpa pengawet</strong>, diseduh <em>setiap pagi</em>.</p>
<!-- Gambar dengan alt, ukuran, dan lazy loading -->
<img src="kopi.jpg" alt="Segelas es kopi susu dengan lapisan gula aren di dasar gelas"
width="600" height="400" loading="lazy">
<h2>Kenapa pilih kami</h2>
<ul>
<li>Biji kopi lokal dari Garut</li>
<li>Gula aren asli</li>
<li>Bisa pesan antar</li>
</ul>
<h2>Cara pesan</h2>
<ol>
<li>Isi formulir di bawah</li>
<li>Tunggu konfirmasi via WhatsApp</li>
<li>Bayar saat pesanan tiba</li>
</ol>
<table>
<caption>Daftar harga</caption>
<thead>
<tr><th scope="col">Menu</th><th scope="col">Harga</th></tr>
</thead>
<tbody>
<tr><th scope="row">Kopi susu aren</th><td>Rp18.000</td></tr>
<tr><th scope="row">Americano</th><td>Rp15.000</td></tr>
</tbody>
</table>
<h2>Formulir pemesanan</h2>
<form action="/pesan" method="post">
<label for="nama">Nama</label>
<input id="nama" name="nama" type="text" required minlength="2">
<label for="email">Email</label>
<input id="email" name="email" type="email" required>
<label for="jumlah">Jumlah gelas</label>
<input id="jumlah" name="jumlah" type="number" min="1" max="20" value="1">
<label for="tanggal">Tanggal kirim</label>
<input id="tanggal" name="tanggal" type="date">
<fieldset>
<legend>Tingkat manis</legend>
<input id="manis-normal" type="radio" name="manis" value="normal" checked>
<label for="manis-normal">Normal</label>
<input id="manis-kurang" type="radio" name="manis" value="kurang">
<label for="manis-kurang">Kurang manis</label>
</fieldset>
<label for="catatan">Catatan</label>
<textarea id="catatan" name="catatan" rows="3"></textarea>
<button type="submit">Kirim pesanan</button>
</form>
<p>Ada pertanyaan? <a href="mailto:halo@kopisenja.id">Email kami</a> atau
<a href="https://maps.google.com" target="_blank" rel="noopener noreferrer">lihat lokasi</a>.</p>
</body>
</html>
<!-- → Halaman tampil dengan judul, gambar, list, tabel harga, dan form.
Klik "Kirim pesanan" dengan email kosong → browser menampilkan peringatan bahwa kolom wajib diisi. -->
Coba buka DevTools (F12), lalu tab Elements. Di sana kamu bisa melihat pohon DOM hasil bacaan browser. Kalau ada tag yang lupa kamu tutup, browser akan "menebak" penutupnya, dan tebakan itu sering tidak sesuai keinginanmu.
Kesalahan umum
- Lupa
<meta name="viewport">. Akibatnya halaman tampak kecil di HP dan media query tidak bekerja seperti harapan. Cara benar: selalu pasang meta viewport di setiap halaman. - Input tanpa
nameatau tanpa<label>. Data tidak terkirim ke server, dan pengguna screen reader tidak tahu kolom itu untuk apa. Cara benar: setiap input punyaname,id, dan<label for="id-yang-sama">. - Memakai
<br>berulang untuk memberi jarak. Jarak adalah urusan CSS (margin). Cara benar: pisahkan isi dengan<p>, atur jarak di CSS. - Memakai
<table>untuk tata letak. Ini kebiasaan era 2000-an yang merusak aksesibilitas dan tampilan responsif. Cara benar: tabel hanya untuk data, tata letak pakai Flexbox atau Grid. - Mengosongkan
altpada gambar yang membawa informasi.alt=""hanya untuk gambar dekoratif. Gambar produk atau infografis butuh deskripsi.
Latihan
- Mudah, Buat halaman
profil.htmlberisi kerangka dokumen lengkap (doctype, lang, charset, viewport, title), satu<h1>berisi nama kamu, satu paragraf perkenalan, dan list tiga hobi. - Sedang, Tambahkan tabel jadwal belajar mingguan (kolom: Hari, Materi, Durasi) lengkap dengan
<caption>,<thead>,<tbody>, danscope. - Menantang, Buat form pendaftaran bootcamp: nama (wajib), email (wajib), nomor WhatsApp (
tel, pola 10 sampai 13 digit), tanggal lahir, pilihan kelas (radio: Pagi/Malam), minat (checkbox: Frontend/Backend/UI), dan unggah CV (hanya PDF).
Lihat solusi
<!-- Soal 1 -->
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Profil Rina</title>
</head>
<body>
<h1>Rina Kartika</h1>
<p>Halo, saya sedang belajar menjadi web developer.</p>
<ul>
<li>Membaca</li>
<li>Bersepeda</li>
<li>Memasak</li>
</ul>
</body>
</html>
<!-- Soal 2 -->
<table>
<caption>Jadwal belajar mingguan</caption>
<thead>
<tr><th scope="col">Hari</th><th scope="col">Materi</th><th scope="col">Durasi</th></tr>
</thead>
<tbody>
<tr><th scope="row">Senin</th><td>HTML</td><td>2 jam</td></tr>
<tr><th scope="row">Rabu</th><td>CSS</td><td>2 jam</td></tr>
<tr><th scope="row">Jumat</th><td>SCSS</td><td>1 jam</td></tr>
</tbody>
</table>
<!-- Soal 3 -->
<form action="/daftar" method="post" enctype="multipart/form-data">
<label for="nama">Nama lengkap</label>
<input id="nama" name="nama" type="text" required>
<label for="email">Email</label>
<input id="email" name="email" type="email" required>
<label for="wa">Nomor WhatsApp</label>
<input id="wa" name="wa" type="tel" pattern="[0-9]{10,13}" placeholder="081234567890">
<label for="lahir">Tanggal lahir</label>
<input id="lahir" name="lahir" type="date">
<fieldset>
<legend>Kelas</legend>
<input id="pagi" type="radio" name="kelas" value="pagi" required>
<label for="pagi">Pagi</label>
<input id="malam" type="radio" name="kelas" value="malam">
<label for="malam">Malam</label>
</fieldset>
<fieldset>
<legend>Minat</legend>
<input id="fe" type="checkbox" name="minat" value="frontend"><label for="fe">Frontend</label>
<input id="be" type="checkbox" name="minat" value="backend"><label for="be">Backend</label>
<input id="ui" type="checkbox" name="minat" value="ui"><label for="ui">UI</label>
</fieldset>
<label for="cv">CV (PDF)</label>
<input id="cv" name="cv" type="file" accept="application/pdf,.pdf">
<button type="submit">Daftar</button>
</form>
<!-- Catatan: form yang mengunggah file wajib memakai method="post" dan enctype="multipart/form-data". -->
Ringkasan
- Setiap halaman dimulai dengan
<!DOCTYPE html>,<html lang="id">, lalu<head>dan<body>. charset,viewport, dantitleadalah tiga isi<head>yang wajib ada.- Elemen bisa bersarang; yang dibuka terakhir ditutup duluan. Void element seperti
<img>tidak punya penutup. - Gambar butuh
alt,width, danheight; link ke situs luar dengantarget="_blank"sebaiknya diberirel="noopener noreferrer". - Tabel hanya untuk data. Form butuh
namedi setiap input,<label>yang terhubung, dantypeinput yang tepat.