Caption dan Deskripsi Tabel
Memberi setiap tabel identitas yang jelas: caption sebagai judul resmi dan aria-describedby untuk menjelaskan tabel yang kompleks.
Masalahnya: Tabel Tanpa Identitas
Bayangkan membuka halaman berisi lima tabel sekaligus: daftar harga, jadwal, nilai, stok, dan laporan. Pengguna screen reader berpindah antar tabel hanya dengan menekan tombol T. Tanpa judul, yang mereka dengar cuma "tabel, 4 kolom, 6 baris", "tabel, 3 kolom, 8 baris". Tidak ada yang memberi tahu tabel mana yang sedang dibaca. Itulah masalah yang dipecahkan caption dan deskripsi tabel: memberi setiap tabel sebuah identitas.
Tabel yang kamu lihat dengan mata langsung dapat konteks dari judul di sekitarnya. Pengguna screen reader tidak seberuntung itu, karena judul di luar tabel belum tentu terbaca sebagai bagian dari tabel. Solusinya ada di dalam HTML sendiri.
caption: Judul Resmi Tabel
<caption> adalah elemen judul yang menjadi bagian dari tabel. Ia wajib menjadi anak pertama dari <table>, sebelum thead, tbody, atau tr mana pun.
<table border="1">
<caption>Harga kopi per ukuran gelas, diperbarui Oktober 2026</caption>
<tr>
<th scope="col">Menu</th>
<th scope="col">Reguler</th>
<th scope="col">Besar</th>
</tr>
<tr>
<th scope="row">Kopi Tubruk</th>
<td>Rp15.000</td>
<td>Rp18.000</td>
</tr>
</table>Screen reader mengumumkan caption sebagai nama tabel sebelum membacakan isinya, misalnya "Tabel: Harga kopi per ukuran gelas". Itu beda besar dengan heading h2 di luar tabel yang hanya dibaca kalau pengguna kebetulan menavigasi ke sana.
Secara visual, caption tampil di atas tabel secara default. Kamu bisa memindahkannya ke bawah dengan CSS caption-side: bottom, tapi posisinya di HTML tetap harus pertama.
aria-describedby untuk Tabel Kompleks
Caption idealnya singkat, satu baris. Tapi bagaimana kalau tabelmu butuh penjelasan panjang, misalnya satuan yang dipakai, cara membaca angka, atau sumber data? Di sinilah aria-describedby berperan: ia menautkan tabel ke paragraf deskripsi di luar tabel.
<p id="catatan-laporan">
Angka dalam jutaan rupiah. Kolom "Q3" memakai data
sementara per 30 September. Sel kosong berarti data belum masuk.
</p>
<table border="1" aria-describedby="catatan-laporan">
<caption>Laporan penjualan per kuartal 2026</caption>
<thead>
<tr>
<th scope="col">Wilayah</th>
<th scope="col">Q1</th>
<th scope="col">Q2</th>
<th scope="col">Q3</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">Bandung</th>
<td>120</td>
<td>145</td>
<td>130</td>
</tr>
<tr>
<th scope="row">Jakarta</th>
<td>210</td>
<td></td>
<td>198</td>
</tr>
</tbody>
</table>Saat pengguna screen reader masuk ke tabel ini, mereka mendengar caption dulu, lalu deskripsi dari paragraf yang ditautkan. Polanya jelas: caption untuk "ini tabel apa", aria-describedby untuk "begini cara membacanya".
Kapan Caption Wajib
Aturannya sederhana:
- Wajib kalau halaman punya lebih dari satu tabel, atau tabelnya memuat data penting (harga, nilai, jadwal). Tanpa caption, tabel tidak punya nama.
- Boleh dilewatkan hanya kalau tabelnya satu-satunya di halaman DAN konteksnya sudah sangat jelas dari heading tepat di atasnya. Tapi jujur saja, menambahkan caption hampir tidak pernah merugikan.
- Jangan pakai caption untuk tabel yang dipakai sebagai layout (yang memang seharusnya tidak dipakai untuk layout sejak awal).
Kesalahan Umum: Salah vs Benar
<!-- SALAH: caption ditaruh di akhir, maknanya rusak -->
<table border="1">
<tr><th scope="col">Nama</th></tr>
<tr><td>Andi</td></tr>
<caption>Nilai siswa</caption>
</table>
<!-- BENAR: caption selalu jadi anak pertama -->
<table border="1">
<caption>Nilai siswa</caption>
<tr><th scope="col">Nama</th></tr>
<tr><td>Andi</td></tr>
</table>Kesalahan lain yang sering muncul: memakai <figcaption> untuk tabel. figcaption adalah pasangan dari <figure>, bukan <table>. Untuk tabel, selalu <caption>. Dan satu tabel hanya boleh punya satu caption.
Catatan teknis: Atribut lawas
summarypada<table>sudah usang dan tidak boleh dipakai lagi. Kalau butuh deskripsi panjang yang tidak ingin terlihat secara visual, sembunyikan paragraf deskripsinya dengan CSS (misalnya kelas visually-hidden) lalu tautkan lewataria-describedby, jangan pakaisummary.
Rangkuman
Setiap tabel data layak punya nama lewat <caption> sebagai anak pertama, dan tabel kompleks layak punya penjelasan lewat aria-describedby. Dua baris tambahan ini mengubah tabel anonim menjadi tabel yang bisa dipahami semua orang.
export default function App(): JSX.Element { return <h1>Hello world</h1> }
Tantangan
Beri Nama pada Tabel
Playground berisi tabel tanpa identitas ditambah satu paragraf penjelasan yang menganggur. Tugasmu: tambahkan caption sebagai anak pertama tabel, lalu tautkan paragraf penjelasan dengan aria-describedby. Tabel tanpa nama membingungkan pengguna screen reader, jadi ini skill aksesibilitas yang wajib dikuasai.
<!doctype html> <html lang="id"> <head> <meta charset="utf-8" /> <title>Tanpa Nama</title> </head> <body> <p id="info-jadwal">Jadwal dalam WIB. Kelas dimulai tepat waktu.</p> <table border="1"> <tr> <th scope="col">Hari</th> <th scope="col">Mapel</th> <th scope="col">Jam</th> </tr> <tr> <th scope="row">Senin</th> <td>Matematika</td> <td>07.00</td> </tr> </table> </body> </html>