Sepanjang section ini, praktik aksesibilitas telah menyertai setiap chapter: th untuk sel judul, caption untuk konteks, scope untuk relasi eksplisit, dan penghindaran penggabungan sel yang tidak perlu. Chapter penutup section Tables ini merangkum semuanya menjadi satu daftar kerja, menambahkan satu teknik terakhir untuk header bertingkat, lalu menutup dengan cara menguji hasilnya menggunakan pembaca layar. Dengan pola ini, tabel yang kita tulis dapat dibaca siapa pun, termasuk pengunjung yang mendengarkan halaman alih-alih melihatnya.
Daftar Praktik yang Terkumpul #
Sebelum menambah teknik baru, kita kunci dulu kebiasaan yang telah dibangun pada chapter-chapter sebelumnya:
- Sel header ditulis
thdan sel data ditulistd; pedoman W3C WAI menyebut pembedaan ini sebagai syarat tabel yang dapat diakses. - Setiap tabel data memiliki
captionsebagai anak pertamatable. scope="col"danscope="row"mempertegas cakupan setiap header.- Penggabungan sel diperlakukan sebagai pilihan terakhir, bukan gaya penulisan.
- Tabel hanya untuk data tabular; tata letak halaman diserahkan pada CSS.
Kelima kebiasaan tersebut berdiri di atas satu prinsip yang sama dengan section Lists dan Semantic HTML: pilih elemen karena maknanya. Prinsip itu kini kita terapkan pada situasi yang paling menuntut, yaitu tabel dengan header bertingkat.
Atribut headers dan id untuk Header Kompleks #
Atribut scope mencukupi selama setiap header berlaku pada satu kolom atau satu baris. Persoalan muncul pada tabel dengan header bertingkat, misalnya kolom semester yang membagi diri menjadi kuartal-kuartal. Untuk relasi semacam itu, kita memberi id pada setiap th, lalu sel data merujuk seluruh header yang relevan melalui atribut headers yang berisi daftar id dipisahkan spasi.
Pedoman WAI menyarankan pasangan id dan headers untuk tabel yang header selnya tidak dapat diasosiasikan secara horizontal atau vertikal saja. Pembaca layar membaca gabungan header tersebut ketika sel data sedang dibaca, sehingga pengunjung mendengar misalnya “Kaos, Semester 1, Kuartal 1, 410” tanpa harus mengingat posisi kolomnya. Relasi menjadi eksplisit di markup, bukan hasil tebakan posisi.
Contoh: Tabel dengan Header Bertingkat #
Toko Budi melaporkan penjualan dua produk dalam empat kuartal yang dikelompokkan menjadi dua semester. Kita bangun tabelnya dengan dua baris header dan simpan sebagai tabel-kompleks.html:
<!doctype html>
<html lang="id">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Penjualan Toko Budi</title>
</head>
<body>
<h1>Penjualan Toko Budi</h1>
<table>
<caption>Penjualan per Kuartal Tahun Ini</caption>
<tr>
<th rowspan="2">Produk</th>
<th id="s1" colspan="2">Semester 1</th>
<th id="s2" colspan="2">Semester 2</th>
</tr>
<tr>
<th id="q1">Kuartal 1</th>
<th id="q2">Kuartal 2</th>
<th id="q3">Kuartal 3</th>
<th id="q4">Kuartal 4</th>
</tr>
<tr>
<th scope="row">Kaos</th>
<td headers="s1 q1">410</td>
<td headers="s1 q2">385</td>
<td headers="s2 q3">402</td>
<td headers="s2 q4">451</td>
</tr>
<tr>
<th scope="row">Topi</th>
<td headers="s1 q1">130</td>
<td headers="s1 q2">142</td>
<td headers="s2 q3">155</td>
<td headers="s2 q4">168</td>
</tr>
</table>
</body>
</html>Output yang Dihasilkan:
Jendela browser menampilkan:
- Baris header pertama: "Semester 1" dan "Semester 2",
masing-masing membentang dua kolom
- Baris header kedua: empat label kuartal
- Kolom Produk membentang dua baris di sisi kiriMari kita telaah peran setiap bagian:
- Baris 11 (
caption): judul tabel tetap hadir sebagai anak pertamatable. - Baris 12-16 (baris header pertama):
thProduk denganrowspan="2"serta duathsemester yang membawaiddancolspan="2". - Baris 17-22 (baris header kedua): empat
thkuartal, masing-masing membawaidyang nantinya dirujuk oleh sel data. - Baris 24-28 dan 30-36 (sel data): setiap
tdmemuatheadersseperti"s1 q1", yang menggabungkan header semester dan header kuartal untuk sel tersebut.
Tabel Data versus Tabel Layout #
Satu penegasan penutup tentang larangan yang kita bahas di awal section: tabel layout membuat pembaca layar membuka mode tabel untuk konten yang bukan data. Pengunjung mendengar pengumuman baris dan kolom untuk halaman yang sebenarnya tidak memiliki struktur data, sehingga halaman menjadi lebih sulit diikuti. Kebiasaan yang menjaga: setiap kali menemukan table dalam kode, pastikan isinya memang data tabular; bila tujuannya tata letak, gunakan CSS.
Menguji dengan Mode Navigasi Tabel #
Cara paling jujur menguji tabel adalah mendengarkannya seperti pengunjung yang bergantung pada pembaca layar. Prosedur ringkasnya:
- Buka halaman dengan pembaca layar; NVDA merupakan pilihan gratis yang populer.
- Masuk ke dalam tabel, lalu gunakan mode navigasi tabel; pada NVDA, sel berpindah dengan kombinasi
Ctrl+Altbersama tombol panah. - Dengarkan pengumuman saat berpindah sel: caption, header kolom, dan header baris seharusnya terucap sebelum nilai data.
- Catat sel yang header-nya tidak terucap, lalu perbaiki markup dengan
scopeatau pasanganheadersdanid.
Dengan prosedur ini, section Tables tuntas dari struktur paling kecil hingga tabel bertingkat yang teruji. Materi berikutnya beralih ke section Semantic HTML, yang memperluas prinsip yang sama, yaitu memilih elemen karena maknanya, ke seluruh bagian struktur halaman.
Referensi resmi untuk pendalaman:
- W3C WAI — Tables Tutorial
- MDN Web Docs — Elemen td
- MDN Web Docs — Elemen caption
- WHATWG — HTML Living Standard: Tabular data
Berkas Sumber
Berkas pendukung halaman ini dapat diunduh dan dijalankan langsung sesuai penjelasan di atas.
tabel-kompleks.html
Unduh berkas<!doctype html>
<html lang="id">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Penjualan Toko Budi</title>
</head>
<body>
<h1>Penjualan Toko Budi</h1>
<table>
<caption>Penjualan per Kuartal Tahun Ini</caption>
<tr>
<th rowspan="2">Produk</th>
<th id="s1" colspan="2">Semester 1</th>
<th id="s2" colspan="2">Semester 2</th>
</tr>
<tr>
<th id="q1">Kuartal 1</th>
<th id="q2">Kuartal 2</th>
<th id="q3">Kuartal 3</th>
<th id="q4">Kuartal 4</th>
</tr>
<tr>
<th scope="row">Kaos</th>
<td headers="s1 q1">410</td>
<td headers="s1 q2">385</td>
<td headers="s2 q3">402</td>
<td headers="s2 q4">451</td>
</tr>
<tr>
<th scope="row">Topi</th>
<td headers="s1 q1">130</td>
<td headers="s1 q2">142</td>
<td headers="s2 q3">155</td>
<td headers="s2 q4">168</td>
</tr>
</table>
</body>
</html>