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 th dan sel data ditulis td; pedoman W3C WAI menyebut pembedaan ini sebagai syarat tabel yang dapat diakses.
  • Setiap tabel data memiliki caption sebagai anak pertama table.
  • scope="col" dan scope="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:

text
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 kiri

Mari kita telaah peran setiap bagian:

  1. Baris 11 (caption): judul tabel tetap hadir sebagai anak pertama table.
  2. Baris 12-16 (baris header pertama): th Produk dengan rowspan="2" serta dua th semester yang membawa id dan colspan="2".
  3. Baris 17-22 (baris header kedua): empat th kuartal, masing-masing membawa id yang nantinya dirujuk oleh sel data.
  4. Baris 24-28 dan 30-36 (sel data): setiap td memuat headers seperti "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:

  1. Buka halaman dengan pembaca layar; NVDA merupakan pilihan gratis yang populer.
  2. Masuk ke dalam tabel, lalu gunakan mode navigasi tabel; pada NVDA, sel berpindah dengan kombinasi Ctrl+Alt bersama tombol panah.
  3. Dengarkan pengumuman saat berpindah sel: caption, header kolom, dan header baris seharusnya terucap sebelum nilai data.
  4. Catat sel yang header-nya tidak terucap, lalu perbaiki markup dengan scope atau pasangan headers dan id.

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:

Berkas Sumber

Berkas pendukung halaman ini dapat diunduh dan dijalankan langsung sesuai penjelasan di atas.

tabel-kompleks.html

Unduh berkas
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>