Elemen div dan span adalah dua wadah generik yang tidak menyatakan makna apa pun, dan keduanya menjadi pilihan terakhir setelah tidak ada elemen semantik yang cocok. Topik ini membahas perbedaan keduanya, penggunaannya yang sah untuk pengelompokan gaya dan skrip, serta cara mengenali markup malas yang menggantikan elemen bermakna. Setelah membacanya, keputusan menambah wadah generik dapat diambil dengan alasan yang jelas.
Dua wadah tanpa makna#
Elemen div adalah wadah generik tingkat blok yang isinya boleh berupa konten aliran (flow content) hampir apa pun, sedangkan span adalah wadah generik sebaris yang isinya terbatas pada konten frasa (phrasing content), yaitu teks dan elemen sebaris. Karena tidak membawa makna, keduanya hanya menambah struktur bagi gaya dan skrip. Pembeda utamanya terletak pada jenis kontennya. Karena itu, span yang membungkus paragraf adalah markup yang tidak valid, dan sebaliknya div yang ditulis di dalam p memicu parser menutup paragrafnya lebih awal.
| Elemen | Jenis konten yang diizinkan | Pemakaian khas |
|---|---|---|
div | Konten aliran (flow) | Pengelompokan blok untuk gaya atau skrip |
span | Konten frasa (phrasing) | Penandaan bagian teks sebaris |
Kedua elemen ini berpasangan dengan jenis kontennya, dan aturan itu menjelaskan hampir semua kesalahan penempatan yang ditemukan pada markup nyata. Apabila isi yang hendak dibungkus memuat paragraf, judul, daftar, atau tabel, wadahnya adalah div. Apabila isinya hanya kata atau frasa di dalam kalimat, wadahnya adalah span.
Penggunaan yang tepat#
Wadah generik sah digunakan setelah elemen semantik yang cocok tidak ditemukan. Kebutuhan yang paling sering muncul ada tiga, yaitu mengelompokkan beberapa elemen menjadi satu area untuk tata letak CSS, memberikan kaitan bagi skrip melalui id atau atribut data-*, dan menandai bagian teks sebaris yang gayanya khusus tanpa makna khusus. Pemisahan peran ini menjaga markup tetap dapat dibaca, karena wadahnya hanya muncul pada titik yang memang membutuhkan kaitan.
<div class="kartu">
<h2>Senin</h2>
<p>Menyapu lantai dan merapikan meja.</p>
</div><p>Panel ditutup pukul <span class="sorot-waktu">16.00</span>.</p>Pada kedua contoh, elemen semantiknya tetap bekerja, yaitu h2 dan p menyatakan maknanya, sedangkan wadah hanya mengelompokkan dan menandai. Kaitan skrip dikerjakan dengan cara yang sama, misalnya div panel diberi id, lalu skrip menemukannya tanpa menyentuh markup lain.
// tidak-dijalankan
const panel = document.querySelector("#panel-jadwal");
panel.querySelector("#tombol-tandai").addEventListener("click", tandaiSelesai);Skrip di atas tidak dijalankan di sini karena membutuhkan dokumen browser, tetapi bentuknya memperlihatkan peran wadah sebagai titik tangkap skrip. Tanpa wadah yang diberi nama, skrip terpaksa menelusuri banyak elemen satu per satu, dan perubahan kecil pada markup langsung merusak pencariannya. Atribut data-* juga dapat menggantikan id apabila satu halaman memuat banyak panel sejenis, karena pencariannya berbasis atribut data, bukan nama tunggal.
Kembalikan makna pada elemen yang tepat#
Markup malas muncul ketika wadah generik digunakan menggantikan elemen yang semestinya. Kasus yang paling merugikan adalah div yang menjadi tombol tiruan dengan pengatur klik. Tombol tiruan tidak dapat menerima fokus papan ketik, tidak merespons tombol Enter, dan tidak diumumkan sebagai tombol oleh pembaca layar (screen reader), sehingga pengguna papan ketik kehilangan aksesnya. Elemen button memberikan seluruh perilaku itu tanpa satu baris skrip pun.
| Kebutuhan | Markup malas | Elemen yang tepat |
|---|---|---|
| Tombol aksi | div dengan pengatur klik | button |
| Paragraf | div | p |
| Judul bagian | div dengan kelas judul | h2 sampai h6 |
| Deret butir | Deretan div bertumpuk | ul atau ol dengan li |
| Sorotan teks sebaris | div di dalam paragraf | span |
Tabel di atas menunjukkan pola yang sama, yaitu hampir setiap markup malas memiliki padanan bawaan yang lebih pendek dan lebih bermakna. Aturan keputusannya dapat dirumuskan singkat, yaitu tanyakan dahulu apakah isi yang dibungkus menyatakan sesuatu, dan bila jawabannya ya, cari elemen yang menyatakannya. Wadah generik baru dipasang pada lapisan terluar untuk mengelompokkan bagian-bagian yang sudah bermakna.
Demo berikut membandingkan tombol tiruan dengan button asli. Tekan tombol Tab beberapa kali, lalu amati baris statusnya, kemudian klik keduanya dengan tetikus untuk melihat perbedaan yang tersisa.
Kode sumber demo
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="utf-8">
<title>Demo fokus tombol</title>
<style>
body { font-family: system-ui, sans-serif; margin: 16px; color: #1e293b; }
.palsu { display: inline-block; margin-right: 8px; padding: 8px 14px; background: #e2e8f0; border: 1px solid #94a3b8; border-radius: 6px; cursor: pointer; }
button { padding: 8px 14px; border: 1px solid #2563eb; background: #dbeafe; border-radius: 6px; cursor: pointer; }
#status { margin-top: 12px; padding: 8px; background: #f8fafc; border: 1px dashed #cbd5e1; min-height: 20px; }
</style>
</head>
<body>
<p>Tekan tombol Tab beberapa kali, lalu amati baris status.</p>
<div class="palsu" id="tombol-div">div sebagai tombol</div>
<button type="button" id="tombol-asli">button asli</button>
<p id="status">Belum ada elemen yang menerima fokus.</p>
<script>
const status = document.getElementById('status');
const divPalsu = document.getElementById('tombol-div');
const tombolAsli = document.getElementById('tombol-asli');
divPalsu.addEventListener('click', () => {
status.textContent = 'div menerima klik tetikus, tetapi Tab tidak pernah mengirim fokus kepadanya.';
});
tombolAsli.addEventListener('focus', () => {
status.textContent = 'button menerima fokus dari Tab dan dapat ditekan dengan Enter.';
});
</script>
</body>
</html>Menyatukan contoh dalam satu berkas#
Berkas berikut menata satu panel jadwal dengan cara yang diuraikan topik ini. Judul, paragraf, dan tombolnya menggunakan elemen bermakna, sedangkan div panel dan div kartu hanya mengelompokkan untuk gaya dan skrip, dan satu span menandai angka jam yang gayanya khusus. Gaya pada bagian head halaman itu sengaja dibuat kecil agar fokusnya tetap pada struktur markupnya.
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Contoh wadah generik</title>
<style>
.panel { border: 1px solid #cbd5e1; border-radius: 6px; padding: 12px; }
.kartu { border-left: 4px solid #94a3b8; padding: 4px 12px; margin-bottom: 8px; }
.sorot-waktu { font-variant-numeric: tabular-nums; color: #334155; }
</style>
</head>
<body>
<h1>Panel jadwal kelas</h1>
<p>Elemen h1, h2, p, dan button di halaman ini menyatakan maknanya,
sedangkan div dan span hanya mengelompokkan untuk gaya dan skrip.</p>
<div class="panel" id="panel-jadwal">
<div class="kartu">
<h2>Senin</h2>
<p>Menyapu lantai dan merapikan meja.</p>
</div>
<div class="kartu">
<h2>Selasa</h2>
<p>Membuang sampah dan membersihkan papan tulis.</p>
</div>
<button type="button" id="tombol-tandai">Tandai selesai</button>
</div>
<p>Panel ditutup pukul <span class="sorot-waktu">16.00</span>.</p>
<script>
const panel = document.querySelector('#panel-jadwal');
panel.querySelector('#tombol-tandai').addEventListener('click', () => {
panel.classList.add('selesai');
});
</script>
</body>
</html>Perhatikan bahwa tidak ada satu pun wadah generik yang menggantikan elemen bermakna pada berkas itu, dan justru setiap wadah diberi kelas yang menyatakan perannya, yaitu panel dan kartu. Apabila halaman itu dibuka dengan pembaca layar, yang terumumkan hanyalah judul, paragraf, dan tombolnya, bukan wadah-wadahnya, dan keadaan itulah tanda bahwa wadah generik dipasang pada tempatnya. Salin berkasnya, lalu uji dengan menekan Tab untuk memastikan tombolnya dapat menerima fokus tanpa skrip tambahan. Apabila tombolnya diganti div yang dilengkapi pengatur klik, gayanya dapat dibuat serupa, tetapi fokus papan ketiknya hilang, dan itulah perbedaan yang tidak dapat ditutupi oleh gaya apa pun.
Kesalahan umum#
Tiga kesalahan berikut melengkapi daftar pembeda antara wadah yang tepat dan wadah yang malas. Ketiganya lahir karena tampilan diutamakan daripada makna.
- Mengganti elemen interaktif dengan
divyang diberi pengatur klik. Fokus papan ketik, respons Enter, dan pengumuman pembaca layar hilang semuanya. Perilaku aslibuttonjuga mencakup status terfokus yang dapat digayakan lewat CSS. Gunakanbuttonuntuk aksi danauntuk berpindah halaman. - Menaruh
divdi dalamp. Paragraf hanya menerima konten frasa, sehingga parser menutup paragrafnya lebih awal dan struktur yang dihasilkan berbeda dari yang tertulis. Pindahkandivke luar paragraf atau gantikan denganspan. - Menumpuk wadah berlapis-lapis tanpa peran. Setiap lapisan menambah kebisingan pada markup dan sulit dijaga, sementara CSS grid dan flexbox modern mengurangi kebutuhan lapisan pembungkus. Wadah yang sah biasanya memiliki kelas atau
idyang menyatakan perannya, dan bila satu lapisan dihapus tanpa efek apa pun, lapisan itu memang tidak diperlukan. Sederhanakan pohon wadah setiap kali satu lapisan tidak memengaruhi gaya maupun skrip.
Ringkasan#
divadalah wadah generik untuk konten aliran, sedangkanspanadalah wadah generik untuk konten frasa, dan keduanya tidak menyatakan makna.- Penggunaan yang sah meliputi pengelompokan untuk tata letak, kaitan skrip melalui
idataudata-*, dan penandaan gaya pada bagian teks. - Elemen bermakna seperti
button,p, dan heading tidak boleh digantikan wadah generik karena perilaku dan aksesibilitasnya ikut hilang. - Wadah generik dipasang terakhir, yaitu setelah elemen semantik yang cocok dipastikan tidak ada.
Referensi#
- Dokumentasi elemen div — MDN — Makna div sebagai wadah aliran generik.
- Dokumentasi elemen span — MDN — Makna span sebagai wadah frasa generik.
- Grouping content — HTML Living Standard (WHATWG) — Definisi resmi div di dalam spesifikasi.
- Text-level semantics — HTML Living Standard (WHATWG) — Definisi resmi span di dalam spesifikasi.