Mengapa Peramban yang "Pemaaf" Justru Bisa Menyembunyikan Bug?
Spesifikasi parser HTML5 dirancang agar tidak pernah gagal menampilkan halaman meskipun pengembang melakukan kesalahan sintaks (misalnya lupa menutup tag <div>, menaruh <div> di dalam <p>, atau salah mengeja nama atribut). Peramban akan berusaha menebak dan "memperbaiki" pohon DOM secara diam-diam di latar belakang.
Namun, perbaikan diam-diam oleh parser HTML sering menimbulkan bug yang membingungkan!
Contoh Nyata: Apa yang Terjadi Jika Anda Menaruh <div> di Dalam <p>?
Menurut spesifikasi HTML, elemen <p> hanya boleh berisi phrasing content (teks dan elemen inline seperti <span>, <a>, <strong>, <code>). Elemen <p> tidak pernah boleh membungkus elemen blok seperti <div>, <section>, atau <table>!
Perhatikan apa yang dilakukan parser HTML jika Anda menulis kode yang salah ini:
<!-- KODE YANG DITULIS PENGEMBANG (SALAH): --> <p class="kotak-berbingkai"> Kalimat pembuka: <div class="isi-kotak">Rincian di dalam kotak</div> </p> <!-- APA YANG SEBENARNYA DIHASILKAN DI POHON DOM OLEH BROWSER: --> <p class="kotak-berbingkai"> Kalimat pembuka: </p> <!-- Browser menutup paksa <p> tepat sebelum <div>! --> <div class="isi-kotak">Rincian di dalam kotak</div> <p></p> <!-- Tag </p> terakhir diabaikan atau diubah menjadi paragraf kosong! -->
Akibatnya, .isi-kotak terlempar keluar dari <p class="kotak-berbingkai"> dan tata letak CSS Anda hancur!
1. Aturan Keturunan (Content Model) yang Paling Sering Dilanggar
Hafalkan 5 larangan bersarang (nesting rules) paling krusial di HTML5 ini:
| Larangan Bersarang | Mengapa Dilarang & Apa Solusinya? |
|---|---|
<a> di dalam <a> atau <button> di dalam <a> (dan sebaliknya) | Interactive Content tidak boleh bersarang di dalam Interactive Content! Pengguna papan ketik dan pembaca layar tidak akan tahu aksi mana yang dipicu saat tombol Enter ditekan. |
Elemen blok (<div>, <ul>, <table>, <h2>) di dalam <p> | Tag pembuka elemen blok akan langsung menutup tag <p> secara paksa. Gunakan <div> jika ingin membungkus beberapa blok. |
Elemen selain <li> (atau <script>/<template>) sebagai anak langsung <ul> / <ol> | Jangan menaruh <div> atau <p> langsung sebagai anak <ul>; masukkan semuanya ke dalam <li> terlebih dahulu! |
<header> atau <footer> di dalam <header> atau <footer> | Tidak diizinkan oleh spesifikasi WHATWG. |
Banyak elemen <main> yang aktif (tidak hidden) dalam satu halaman | Hanya boleh ada satu <main> yang terlihat per dokumen. |
Bagaimana Jika Seluruh Kartu Produk Harus Bisa Diklik, tetapi di Dalamnya Ada Tombol "Simpan Bookmark"?
Karena Anda tidak boleh membungkus seluruh <article> (yang berisi <button>) di dalam satu tag <a href="..."> raksasa, gunakan teknik Stretched Link (Tautan yang Direntangkan lewat CSS ::after):
<article class="kartu-produk">
<h3>
<!-- Tautan hanya membungkus teks judul, tetapi area kliknya direntangkan oleh CSS ::after -->
<a href="/kelas/html/" class="tautan-utama">Kelas HTML Modern</a>
</h3>
<p>Pelajari fondasi web dari nol hingga siap produksi.</p>
<button type="button" class="tombol-bookmark">Simpan Penanda</button>
</article>
.kartu-produk {
position: relative;
}
/* Merentangkan area klik tautan judul ke seluruh permukaan .kartu-produk */
.tautan-utama::after {
content: "";
position: absolute;
inset: 0;
}
/* Mengangkat tombol bookmark agar berada di atas lapisan ::after */
.tombol-bookmark {
position: relative;
z-index: 1;
}
Hasilnya: struktur HTML 100% valid (tidak ada <button> di dalam <a>), urutan fokus tombol Tab sangat bersih, namun pengguna tetikus tetap bisa mengeklik bagian mana saja dari kartu tersebut!
2. Menginspeksi Accessibility Tree di Browser DevTools
Selain pohon DOM biasa, peramban membangun Accessibility Tree (Pohon Aksesibilitas) yang diserahkan kepada pembaca layar sistem operasi. Anda dapat memeriksanya secara langsung tanpa menginstal aplikasi tambahan:
- Buka Developer Tools (
F12) → tab Elements / Inspector. - Di panel sebelah kanan (tempat tab Styles dan Computed berada), buka sub-tab Accessibility (atau, di Chrome, klik ikon orang kecil "Switch to Accessibility Tree view" di pojok kanan atas pohon DOM; di Firefox, buka panel Accessibility tersendiri di Developer Tools).
- Klik sebuah elemen (misalnya
<button>,<input>, atau<nav>), lalu periksa tiga informasi kunci ini:- Role (Peran): Apakah perannya
button,link,navigation,dialog, atau hanyageneric? - Computed Name (Nama Terhitung): Apakah elemen tersebut memiliki nama yang jelas (misalnya
"Unduh Materi"), atau justru kosong""? - Focusable: Apakah bernilai
true?
- Role (Peran): Apakah perannya
3. Daftar Periksa Audit HTML Siap Produksi
Gunakan daftar periksa 10 poin ini sebelum menandai halaman HTML Anda selesai:
- Dokumen & Bahasa:
<!DOCTYPE html>di baris pertama, serta<html lang="id">telah terpasang. - Kepala Dokumen:
<meta charset="utf-8">berada di awal<head>, diikuti<meta name="viewport" content="width=device-width, initial-scale=1.0">(tanpauser-scalable=no),<title>unik,<meta name="description">, dan<link rel="canonical">. - Landmark Utama: Memiliki
<header>,<nav>, tepat satu<main>, dan<footer>beserta skip link menuju#main. - Hierarki Heading: Memiliki satu
<h1>utama dan subjudul<h2>–<h6>yang berurutan tanpa melompati tingkat hanya demi ukuran huruf. - Kejelasan Semantik Interaksi: Semua navigasi URL menggunakan
<a href="...">, dan semua aksi dalam halaman menggunakan<button type="...">(tidak ada<div onclick>atau<a href="#">). - Gambar & Media: Setiap
<img>memiliki atributalt(deskriptif untuk gambar informatif,alt=""untuk gambar dekoratif), memilikiwidthdanheight, menggunakanfetchpriority="high"pada gambar LCP teratas, danloading="lazy"pada gambar di bawah layar. - Tabel Data: Menggunakan
<caption>,<thead>,<tbody>, dan<th scope="col|row">. - Formulir: Setiap kontrol memiliki
<label for="...">yang terhubung dan atributnamesertaautocompleteyang sesuai. - Komponen Interaktif: Modal menggunakan
<dialog>(showModal()), akordeon menggunakan<details>/<summary>, dan panel sembul menggunakanpopover. - Pemuatan Skrip:
<script>menggunakantype="module"atau atributdefer.
Latihan Praktik: Mengaudit dan Memperbaiki Halaman dengan 5 Kesalahan Struktural
Perhatikan cuplikan markup bermasalah berikut:
<!-- KODE BERMASALAH UNTUK DIAUDIT: -->
<a href="/kelas/css" class="kartu">
<p>
<h4>Kelas CSS Modern</h4>
<div class="ringkasan">Belajar Grid dan Container Queries.</div>
</p>
<button onclick="daftar()">Daftar Sekarang</button>
</a>
Buatlah berkas hasil-audit.html yang memperbaiki seluruh kesalahan model konten pada cuplikan di atas (mengeluarkan <button> dari dalam <a> menggunakan pola stretched link, memperbaiki hierarki heading, dan mengganti <p> yang membungkus elemen blok).