Membaca satu baris tabel lebar dari kiri ke kanan melelahkan: mata mudah melompat ke baris atas atau bawahnya. Zebra striping menjawabnya dengan latar bergantian yang menempel pada baris tanpa perlu kursor — pola ini sudah kita singgung pada chapter :nth-child() di section Pseudo-classes dan Pseudo-elements, dan kini waktunya memakainya sungguhan pada tabel. Chapter ini merapikan pola dasarnya, menjelaskan satu jebakan penghitungan yang melibatkan thead, lalu memadukan striping dengan desain tanpa garis dan state hover.
Pola Dasar: odd dan even #
Satu deklarasi selector memberi latar bergantian pada seluruh baris data:
.tabel-transaksi tbody tr:nth-child(odd) {
background-color: #f6f8f7;
}Demo berikut menerapkan satu deklarasi itu pada enam baris data:
Kata kunci odd dan even menggantikan formula 2n + 1 dan 2n — bacaan yang lebih mudah dipindai dalam CSS. Memilih garis atas atau garis bawah sebagai titik awal hanya soal selera; yang penting satu halaman memakai pola yang konsisten.
Perhatikan bahwa yang diberi latar adalah tr, bukan td. Latar pada tr memenuhi seluruh lebar baris sekaligus — satu deklarasi untuk semua kolom. Memberi latar pada td juga bisa, tetapi bila kolomnya berjarak (mode separate dengan border-spacing), latar per sel akan terputus pada jarak antarsel dan polanya bocor.
Mengapa Scopenya tbody #
Jebakan :nth-child() menyangkut cara ia menghitung: posisi dihitung terhadap induk masing-masing elemen, bukan terhadap tabel. Bila selector ditulis tanpa tbody:
.tabel-transaksi tr:nth-child(odd) {
background-color: #f6f8f7;
}Demo berikut memakai selector tanpa tbody itu pada tabel berheader — perhatikan baris yang terkena latar:
Baris header ikut bergaris karena satu-satunya tr milik thead adalah anak pertama (ganjil) dari induknya. Lebih licik lagi, penghitungan “di-reset” per grup: baris pertama tbody juga anak pertama dari tbody, sehingga header dan baris data pertama bergaris bersamaan — polanya bergeser dari yang kita bayangkan.
Dengan menyertakan tbody, perhitungan tetap berjalan pada satu kelompok baris data yang homogen dan polanya pasti. Aturan praktisnya: selalu tulis tbody tr:nth-child(...) untuk striping, sekalipun tabelmu saat ini belum punya baris header.
Striping pada Desain Tanpa Garis #
Zebra striping dan garis pemisah baris melayani tujuan yang sama — memisahkan baris — dan memakai keduanya sekaligus menumpuk sinyal. Tren desain tabel modern memilih salah satu, dan kombinasi striping tanpa garis memberi tampilan paling lapang:
.tabel-transaksi {
width: 100%;
border-collapse: collapse;
font-size: 14px;
}
.tabel-transaksi th,
.tabel-transaksi td {
padding: 11px 14px;
text-align: left;
}
.tabel-transaksi thead th {
border-bottom: 2px solid #1f6f54;
}
.tabel-transaksi tbody tr:nth-child(odd) {
background-color: #f6f8f7;
}- Sel diberi padding lega tanpa border apa pun.
- Hanya header yang memperoleh garis bawah tebal sebagai tanda bagian.
- Baris data dipisahkan murni oleh latar bergantian.
Demo berikut memakai desain tanpa garis vertikal, striping pada tbody, dan hover yang lebih gelap:
Warna striping sebaiknya sangat dekat dengan putih — kontras yang terlalu tinggi justru menyita perhatian dari datanya. Palet netral seperti #f6f8f7 atau campuran warna tema lewat color-mix(in oklab, #1f6f54, white 94%) sama-sama bekerja; yang penting sel data tetap jauh lebih kontras daripada latarnya.
Hover di Atas Garis #
Pada tabel interaktif, hover melengkapi striping dengan umpan balik yang mengikuti kursor. Urutan penulisan aturan jadi menentukan:
.tabel-transaksi tbody tr:nth-child(odd) {
background-color: #f6f8f7;
}
.tabel-transaksi tbody tr:hover {
background-color: #eef4f1;
}Kedua selector memiliki bobot specificity yang sama — satu pseudo-class, satu element — sehingga cascade menyelesaikannya lewat urutan: aturan :hover yang ditulis terakhir menang saat kursor berada di atas baris bergaris. Bila urutannya terbalik, baris ganjil tidak lagi bereaksi terhadap hover. Warna hover dipilih sedikit lebih gelap dari warna striping agar kedua state terbedakan.
Ringkasan #
Zebra striping memakai tbody tr:nth-child(odd) — scope tbody wajib karena :nth-child() menghitung per induk dan baris header bisa ikut bergaris bila perhitungannya bocor. Pola ini paling bersih dipadukan dengan desain tanpa garis vertikal, dan hover ditulis setelah aturan striping agar tetap menang saat keduanya berlaku. Tabel yang sudah nyaman di layar lebar kini menghadapi ujian terakhir: bagaimana tetap terbaca ketika layarnya hanya selebar ponsel.