Cards & Lists — UI/UX

Card Pattern — Menampilkan Konten Modular Card adalah container yang mengelompokkan informasi terkait. Ini pattern paling umum di UI modern. Anatomi Card…

Card adalah kotak yang mengumpulkan semua informasi tentang satu hal: foto, nama, keterangan, dan aksinya. List adalah deretan baris untuk banyak hal yang sejenis, satu baris per hal. Bayangin dua buku milik Bu Sri. Brosurnya menampilkan tiap kamar di halamannya sendiri dengan foto besar, karena tamu memilih dengan melihat. Buku tamunya berisi satu pesanan per baris, karena Bu Sri membacanya dari atas ke bawah dan membandingkan tanggalnya. Brosur itu card, buku tamu itu list.

🧪 Tebakan cepat: Supaya seluruh kartu Kamar Teras bisa diketuk, Bu Sri membungkus kartunya dengan <a href="/kamar/teras">. Di dalam kartu itu ada link kedua, "Tanya lewat WhatsApp". Browser membaca HTML-nya. Di mana link WhatsApp itu berakhir? Jawabannya ada di bagian "Satu area klik per kartu".

Card atau list

Card List
Isinya sedikit, dan gambarnya penting banyak, seragam, gambar gak wajib
Cara dibaca dilihat satu per satu dipindai dan dibandingkan dari atas ke bawah
Di Homestay Kabut tiga kamar untuk dipilih tamu 16 pesanan Desember di dasbor Bu Sri

Ukurannya, di HP 375px (diukur di Chromium, WebKit, dan Firefox):

Isi Satu item Terlihat di area dasbor 664px
Kamar sebagai card (foto 4:3, nama, harga, link) 443px 1 kamar
Pesanan sebagai card, dengan foto kamar 379px + jarak 16px 664 ÷ 395 = 1,68, jadi 1 dari 16
Pesanan sebagai list (baris 37px) 37px 664 ÷ 37 = 17,9, jadi ke-16 pesanan

Untuk tiga kamar, satu kamar per layar justru pas: tamu memang memutuskan dengan melihat fotonya. Untuk 16 pesanan, card membuat Bu Sri menggulir 16 kali; list memuat semuanya sekaligus.

Anatomi card

Urutannya dari atas ke bawah: gambar, judul, keterangan, aksi. Gambar menarik mata, judul memberi nama, keterangan memberi alasan, dan aksi di bawah sebagai langkah berikutnya.

<article class="card">
  <img class="card-image" src="kamar-teras-800.jpg" width="1200" height="900" alt="">
  <div class="card-body">
    <h3><a class="card-link" href="/kamar/teras">Kamar Teras</a></h3>
    <p>Kasur dobel, jendela ke arah gunung. 2 tamu.</p>
    <p class="price">Rp 350.000 / malam</p>
    <a class="wa" href="https://wa.me/6281234567890">Tanya lewat WhatsApp</a>
  </div>
</article>

<style>
  .card { position: relative; border-radius: 0.75rem; border: 1px solid #E5E7EB; overflow: hidden; background: #fff; }
  .card-image { display: block; width: 100%; height: auto; }
  .card-body { padding: 1.25rem; }
</style>

Di latihan nanti, nilainya persis ini: <article class="card"> dengan border-radius: 0.75rem dan overflow: hidden, dan .card-body dengan padding: 1.25rem.

Satu area klik per kartu

Membungkus seluruh kartu dengan <a> terlihat praktis, tapi HTML gak mengizinkan link di dalam link. Kami menguji kode Bu Sri di Chromium, WebKit, dan Firefox. Ketiganya membangun pohon yang sama:

article.card
  a.card-cover          (link pertama, cuma berisi foto)
    img.card-image
  div.card-body
    a.card-cover        (salinan link pertama: judul, keterangan, harga)
      h3, p, p.price
    a.wa                (link WhatsApp, berdiri sendiri)

Begitu bertemu <a> kedua, parser menutup link pertama, lalu membuka salinannya untuk sisa isinya. Jadi jawaban tebakannya: link WhatsApp berakhir di luar link kartu, dan link kartunya terpecah jadi dua. Itu jawaban tebakannya. Selain itu, nama link yang membungkus kartu adalah seluruh teks di dalamnya, jadi pembaca layar membacakan "Kamar Teras Kasur dobel, jendela ke arah gunung. 2 tamu. Rp 350.000 / malam".

Caranya: satu link pendek di judul, lalu lapisan tak terlihat dari link itu ditarik menutupi seluruh kartu:

.card-link::after { content: ""; position: absolute; inset: 0; } /* lapisan klik selebar kartu */
.card:focus-within { outline: 3px solid #1f2937; outline-offset: 2px; } /* cincin fokus di kartunya */
.wa { position: relative; z-index: 1; } /* link kedua tetap di atas lapisan */

List untuk dasbor Bu Sri

<ul class="list">
  <li class="list-item"><span><b>Rina</b> · Kamar Teras, 1 Des, 2 malam</span><b>Rp 700.000</b></li>
  <li class="list-item"><span><b>Pak Hadi</b> · Kamar Kebun, 2 Des, 1 malam</span><b>Rp 425.000</b></li>
</ul>

<style>
  .list-item { display: flex; justify-content: space-between; gap: 8px; padding: 8px 12px; font-size: 14px; line-height: 20px; border-bottom: 1px solid #e2e8f0; }
  .list-item:last-child { border-bottom: none; }
  .list-item > b { flex: none; white-space: nowrap; } /* total gak boleh patah jadi dua baris */
</style>

⚠️ Jebakan yang sering ketemu

TL;DR: Card mengumpulkan satu hal (gambar, judul, keterangan, aksi, dengan urutan itu) dan cocok untuk sedikit isi yang dipilih dengan melihat, seperti tiga kamar; list menampilkan banyak isi seragam yang dipindai, seperti 16 pesanan (baris 37px memuat semuanya di 664px, card cuma 1). Bungkus card dengan <article>, isi yang berdiri sendiri. Di latihan: .card dengan border-radius: 0.75rem dan overflow: hidden (memotong foto mengikuti sudut), .card-body dengan padding: 1.25rem. Jangan menaruh link di dalam link: browser memecahnya. Buat satu area klik dengan link di judul dan ::after { position: absolute; inset: 0 } di kartu yang position: relative, dan angkat link kedua dengan position: relative; z-index: 1.

Yang akan kamu pelajari