Membuat Kartu

Ringkasan

Kartu mengelompokkan satu konten terkait atau satu pilihan. Ini adalah pola visual, bukan model semantik atau interaksi tetap, jadi pertahankan makna konten dan gunakan interaksi native yang sesuai dengan tujuannya.

Panduan

Pilih semantik untuk konten dan interaksinya secara terpisah:

  • menggunakan <article> sebagai root kartu, baik ditautkan ke tujuan maupun tidak;
  • menggunakan link native untuk navigasi. Jika seluruh kartu adalah satu tujuan, satu link dapat menggabungkan <article> hanya jika kartu tidak berisi elemen interaktif lainnya (a, button, input, select, textarea);
  • mempertahankan link dan tombol untuk tindakan independen sebagai kontrol native terpisah;
  • gunakan tombol pilihan atau kotak centang dengan <label> terkait, atau option dalam <select> native, jika kartu merupakan pilihan.

Pertahankan media, judul, konten pendukung, dan tindakan dalam urutan sumber yang bermakna; jangan gunakan CSS order untuk bertentangan dengannya (lihat Tata Letak CSS dan Desain Responsif).

Penerapan

Buat markup tetap minimal dan biarkan pemilih CSS mengenali setiap wilayah, sehingga kartu sederhana tetap sederhana dan Kartu Informasi tetap dapat dibuat. Kartu memiliki hingga empat region, dalam urutan sumber ini, dan salah satunya dapat dihilangkan. Region adalah turunan langsung dari kartu, tidak dikelompokkan dalam elemen wrapper seperti .card__body, yang mencegah penempatan dan penataan gaya region oleh pemilih. Region dengan satu elemen adalah elemen itu sendiri, tidak digabungkan: paragraf tunggal adalah <p>. Gunakan wrapper hanya jika region berisi beberapa elemen.

  • Media: <img>, <picture>, <video>, atau <svg> sebagai turunan pertama. Tambahkan class .media hanya ke konten utama arbitrer yang bukan salah satu elemen tersebut, dan jangan pernah menggabungkan <img> biasa dalam elemen .media.
  • Header: judul tersendiri. Gunakan <hgroup> hanya jika judul memiliki subjudul atau tagline, dan <header> jika region memiliki lebih dari sekadar judul, seperti baris nama penulis atau badge. Jika kartu memiliki tujuan utama, link akan ditempatkan di dalam judul.
  • Konten: satu <p>, <ul>, atau <dl> berdiri sendiri. Jika konten terdiri dari beberapa elemen, seperti beberapa paragraf atau satu paragraf ditambah daftar, kelompokkan dalam satu <div> sehingga region tersebut menjadi satu item petak.
  • Footer: <footer> yang menyimpan tindakan independen sebagai link dan tombol native. Link "baca selengkapnya" dapat menggunakan URL link judul, tetapi berikan label aksesibilitas deskriptif yang dimulai dengan teks yang terlihat, menggunakan teks yang disembunyikan secara visual (misalnya, Read more<span> about poached eggs</span>), karena link "baca selengkapnya" yang identik bersifat ambigu dalam daftar link pembaca layar. Jangan tambahkan link footer lain yang mengulangi URL judul.

Kartu yang paling sederhana adalah <article> yang berisi judul dan paragraf. Pilih pola link dan tindakan yang sesuai dengan perilaku kartu; lihat Model interaksi.

Untuk gambar atau video kartu yang harus mengisi area rasio tetap, tetapkan aspect-ratio dan object-fit: cover pada <img> atau <video> itu sendiri, sehingga mengisi area tanpa distorsi (pemangkasan dapat terjadi). Gunakan aspect-ratio penampung .media hanya untuk konten utama lainnya. Jika tidak, pertahankan rasio intrinsik media. Berikan teks alternatif yang sesuai untuk gambar informatif; gunakan alt="" untuk gambar dekoratif.

Menyesuaikan dengan ruang yang tersedia

Dasarkan tata letak pada ruang yang tersedia di kartu, bukan area pandang. Untuk menyesuaikan turunan kartu (media, teks, tindakan), jadikan kartu sebagai penampung ukuran (container-type: inline-size) dan tulis aturan @container terhadap turunannya. Hindari menentukan ukuran dari induk petak atau daftar: lebar kartu yang sebenarnya dapat bergantung pada jumlah kolom, celah, dan sebagainya, sehingga titik henti sementara berbasis induk menjadi tidak jelas.

Dalam penampung yang sempit, tumpuk region dalam urutan sumber. Dalam penampung lebar, tempatkan media di kolom samping di samping region lain, tetapi hanya untuk kartu yang memiliki media: cakup aturan tersebut dengan :has() pada turunan media (misalnya .card:has(> img)) sehingga definisi kolom dan penempatan grid-column tidak pernah berlaku untuk kartu tanpa media. Kartu tanpa media tetap satu kolom pada setiap lebar, dan tidak boleh menyediakan kolom media kosong.

Menyejajarkan kartu dalam petak

Jika kartu dalam satu baris harus memiliki tinggi yang sama untuk setiap bagiannya, gunakan subgrid: buat setiap kartu mencakup empat jalur baris bersama (media, header, konten, footer) dan tempatkan bagian berdasarkan pemilih elemen, dengan memperlakukan semua yang bukan media, judul, atau <footer> sebagai konten. Kartu yang menghilangkan suatu region akan membiarkan jalurnya kosong, sehingga region yang tersisa tetap sejajar dengan kartu yang berdekatan. Setiap jalur berisi satu item petak, jadi gabungkan region konten dalam <div> hanya jika memiliki lebih dari satu elemen dan kartu berbagi jalur. Kartu yang tidak sejajar dengan elemen seinduk tidak memerlukan wrapper atau subgrid.

Model interaksi

Kartu konten

Gunakan <article> sebagai root kartu. Pertahankan link dan tombol sebagai kontrol native yang terpisah.

Kartu satu tujuan

Jika seluruh kartu adalah satu tujuan dan tidak memiliki tindakan independen, gunakan satu link native. Link dapat menggabungkan <article>. Jangan menyisipkan link, tombol, atau kontrol formulir lain di dalam link, dan pastikan teks "baca selengkapnya" tetap berupa <p> atau <span> biasa. Karena label aksesibilitas link adalah semua teks kartu, buat kontennya tetap singkat; jika kartu memiliki banyak teks atau tindakan lainnya, gunakan pola link yang direntangkan di bawah ini sehingga hanya judul yang menjadi link:

<a href="/recipes/poached-eggs">
  <article class="card">
    <h3>Poached eggs</h3>
    <p>Two poached eggs served on toasted sourdough.</p>
  </article>
</a>

Kartu yang dapat diklik dengan tindakan independen

Jika mengklik kartu memicu tindakan, bukan membuka halaman, gunakan <button>, bukan link.

Jika kartu konten tertaut ke tujuan utama, juga berisi elemen interaktif lainnya, dan harus dapat diklik secara keseluruhan:

  • Gunakan satu keikutsertaan, pada link utama itu sendiri: tempatkan .card-link di satu link per kartu (link judul). Footer dan link lainnya tidak pernah mendapatkannya, atau masing-masing akan merentangkan overlay-nya sendiri dan yang terakhir akan menangkap seluruh kartu.
  • Tautkan judulnya dan rentangkan area klik kursor di seluruh kartu dengan ::after
.card:has(a.card-link) {
    position: relative;
}

.card a.card-link::after {
    content: "";
    position: absolute;
    inset: 0;
}
  • Tingkatkan elemen interaktif dengan position: relative; z-index: 1 agar tetap dapat dioperasikan. Menargetkan jenis elemen (misalnya, a, button) daripada memerlukan keikutsertaan melalui class.
  • JANGAN terapkan z-index ke seluruh penampung karena akan membuatnya menangkap peristiwa pointer yang tidak menghasilkan tindakan apa pun.
.card:has(a.card-link) {
    /* Keep other interactive elements above the overlay */
    a:not(.card-link), button, input, x-button {
        position: relative;
        z-index: 1;
    }
}
  • Gunakan gaya pada kartu itu sendiri saat kursor diarahkan/difokuskan, bukan pada link yang direntangkan:
.card {
    a.card-link {
        &:focus-visible {
            outline: none; /* Draw it on the card instead */
        }
    }
    
    &:has(a.card-link:focus-visible) {
        /* Focus ring */
    }

    &:has(a.card-link:hover) {
        /* Hover styles */
    }
}

Kartu pilihan

Untuk kartu yang mewakili pilihan yang telah ditentukan, gunakan <label class="card"> dengan kotak centang atau tombol pilihan sebagai turunan langsung.

Terapkan gaya ke kartu yang dipilih dengan :has(:checked). Jangan pernah mengubah properti yang memengaruhi tata letak seperti border-width, padding, atau font-weight pada pilihan, karena kartu dan elemen di sekitarnya akan melompat; gambar penekanan dengan outline, box-shadow, atau batas transparan yang hanya mengubah warna:

.card {
  border: 2px solid transparent;

  &:has(> :checked) {
    border-color: var(--accent);
  }
}

Kotak centang atau tombol pilihan yang terlihat itu sendiri merupakan indikator pilihan non-warna, sehingga perubahan warna saja sudah cukup. Jika kontrol disembunyikan secara visual (tetap dapat difokuskan dan berada di hierarki aksesibilitas, jangan pernah display: none), tambahkan indikator non-warna yang tidak memengaruhi tata letak, seperti ikon centang atau outline yang lebih tebal.

Jika pilihan berada dalam pemilih dropdown yang opsinya disusun sebagai kartu, gunakan <select> native dengan appearance: base-select dan beri gaya pada elemen ::picker(select) dan <option>, bukan mengganti pilihan dengan kartu <div>; lihat Tata Letak Pemilih Kustom untuk mengetahui detail dan penggantian selengkapnya.