Daftar produk, artikel, atau video biasanya disajikan sebagai kartu — dan jumlahnya berubah-ubah tergantung data dari server. Menulis media query untuk setiap kemungkinan jumlah kartu tentu melelahkan. Resep repeat(auto-fit, minmax(220px, 1fr)) memindahkan seluruh perhitungan itu ke browser: jumlah kolom menyesuaikan lebar wadah, dan kartu yang tidak muat otomatis pindah ke baris berikutnya. Kita bedah cara browser menghitung jumlah kolomnya, karena angka hasilnya tidak selalu sesuai intuisi.
Resep Galeri Kartu Responsif #
.galeri {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
gap: 16px;
max-width: 1000px;
margin-inline: auto;
}Setiap kartu adalah <article> dengan struktur yang sama:
<article class="kartu">
<div class="gambar"></div>
<h3>Apel Fuji</h3>
<p>Dipetik dari kebun di Batu, dikirim dalam 24 jam.</p>
</article>Hasil di Browser:
Pada viewport 1280x720, wadah 1000px menghasilkan empat kolom:
computed grid-template-columns "238px 238px 238px 238px".
Kedelapan kartu tersusun dua baris; setiap kartu selebar 238px.Mari kita telusuri cara browser sampai ke empat kolom tersebut:
minmax(220px, 1fr): setiap track minimal selebar 220px, maksimal menyusut-melar mengikuti1fr(lihat repeat-minmax ).- Menghitung jumlah track: gap ikut diperhitungkan. Browser mencari berapa banyak track yang muat dengan rumus
(lebar wadah + gap) / (minimal + gap): (1000 + 16) ÷ (220 + 16) = 4,3 → dibulatkan ke bawah menjadi 4 track. - Membagi sisa ruang: 4 track minimal 220px hanya memakai 1000 − 3 × 16 = 952px ruang track; sisa itu dibagi rata sehingga tiap kartu 952 ÷ 4 = 238px.
Perhatikan langkah kedua: banyak orang menghitung 1000 ÷ 220 = 4,5 dan berharap lima kolom — tapi gap tiga kali 16px membuat lima track tidak muat. Menghitung dengan rumus yang benar sejak awal menghemat waktu debugging.
Nilai minimal juga sensitif terhadap gap. Dengan wadah 1000px dan gap 16px, menaikkan minimal dari 220px menjadi 240px mengurangi jumlah kolom dari empat menjadi tiga: empat track 240px plus tiga gap butuh 1008px — melampaui wadah 8px saja. Karena itu, sebelum mengubah nilai minmax, hitung ulang dengan rumus di atas alih-alih menebak.
auto-fit mencollapse track kosong pada baris terakhir; auto-fill membiarkannya hadir sebagai track kosong. Perbedaan keduanya hanya terasa pada kartu yang jumlahnya sedikit — dibahas lengkap pada chapter Auto-fit dan Auto-fill
.
Dua penyesuaian kecil yang sering dibutuhkan. Pertama, gap dapat menerima dua nilai — gap: 24px 16px memisahkan baris 24px dan kolom 16px — berguna bila kartu yang bertumpuk perlu jarak vertikal lebih besar. Kedua, bila galeri berada di dalam komponen yang lebarnya ditentukan halaman di sekitarnya — bukan viewport — resep ini kompatibel dengan container queries; jumlah kolom kemudian menyesuaikan wadahnya, seperti dibahas pada chapter Container Size Queries
.
Anatomi Kartu yang Rapi #
Kartu terlihat profesional bila tiga halnya konsisten: tinggi gambar, jarak dalam, dan sudut:
.kartu {
background: rgb(255, 255, 255);
border-radius: 12px;
padding: 16px;
box-shadow: 0 1px 3px rgb(15 23 42 / 15%);
}
.kartu .gambar {
aspect-ratio: 16 / 9;
border-radius: 8px;
background: rgb(219, 234, 254);
margin-bottom: 12px;
}aspect-ratio: 16 / 9 membuat semua thumbnail sama tinggi tanpa perlu tahu lebar kartunya di masing-masing breakpoint (lihat aspect-ratio
). Bayangan satu lapis yang ringan (lihat box-shadow
) cukup untuk memisahkan kartu dari latar, dan padding: 16px menjaga teks tidak menempel tepi kartu.
Demo chapter ini memuat penanda uji otomatis yang memverifikasi serialisasi grid-template-columns “238px 238px 238px 238px” serta lebar 238px pada kartu baris pertama dan kartu pertama baris kedua.