kodingup.camp

Beranda/HTML, CSS & SCSS Mastery

Struktur Dasar Dokumen HTML

Modul 1 dari 116 menit bacaDocument Structure Fundamentals

Isi modul

    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:

    Tiga isi <head> yang wajib kamu hafal:

    1. <meta charset="UTF-8"> supaya huruf seperti é, emoji, atau aksara non-Latin tampil benar, bukan jadi simbol aneh.
    2. <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.
    3. <title> yang tampil di tab browser dan di hasil pencarian Google.

    Elemen dasar teks

    <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

    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:

    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

    1. 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.
    2. Input tanpa name atau tanpa <label>. Data tidak terkirim ke server, dan pengguna screen reader tidak tahu kolom itu untuk apa. Cara benar: setiap input punya name, id, dan <label for="id-yang-sama">.
    3. Memakai <br> berulang untuk memberi jarak. Jarak adalah urusan CSS (margin). Cara benar: pisahkan isi dengan <p>, atur jarak di CSS.
    4. 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.
    5. Mengosongkan alt pada gambar yang membawa informasi. alt="" hanya untuk gambar dekoratif. Gambar produk atau infografis butuh deskripsi.

    Latihan

    1. Mudah, Buat halaman profil.html berisi kerangka dokumen lengkap (doctype, lang, charset, viewport, title), satu <h1> berisi nama kamu, satu paragraf perkenalan, dan list tiga hobi.
    2. Sedang, Tambahkan tabel jadwal belajar mingguan (kolom: Hari, Materi, Durasi) lengkap dengan <caption>, <thead>, <tbody>, dan scope.
    3. 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

    Kuis pemahaman

    Pilih satu jawaban per soal. Penjelasan muncul setelah kamu menjawab.