Dengan prinsip, media query, breakpoints, gambar, tipografi, dan navigasi di tangan, saatnya menyusunnya menjadi layout halaman utuh. Kabar baiknya, dua pola sudah menutup mayoritas kebutuhan: layout halaman berbasis grid yang berpindah kolom, dan card grid yang menghitung jumlah kolomnya sendiri. Keduanya memanfaatkan CSS Grid yang telah kita pelajari pada section Grid, kini dipakai sebagai mesin responsif. Chapter ini membangun keduanya langkah demi langkah lewat demo sidebar plus kartu.

Layout Halaman: Sidebar yang Berpindah Posisi #

Pola paling umum di web: konten utama didampingi sidebar. Di ponsel, keduanya menumpuk; mulai breakpoint tertentu, sidebar menempati kolom tetap di samping konten:

css
.halaman {
  display: grid;
  grid-template-columns: 1fr;   /* ponsel: satu kolom, bertumpuk */
  gap: 16px;
  max-width: 900px;
}

@media (min-width: 1024px) {
  .halaman { grid-template-columns: 260px 1fr; }
}

Mari kita telaah potongan di atas:

  1. grid-template-columns: 1fr: pada layar kecil hanya ada satu kolom, sehingga aside dan main menumpuk sesuai urutan penulisan di HTML.
  2. 260px 1fr mulai 1024px: sidebar memperoleh kolom tetap selebar 260px, sedangkan 1fr memberi seluruh sisa ruang pada konten utama. Dengan halaman selebar 900px, hitungannya pasti: 900 - 260 - 16 (gap) = 624px untuk konten.
  3. 260px, bukan persentase: lebar tetap menjaga agar sidebar tidak ikut menyempit di layar lebar; bila ingin sidebar yang ikut tumbuh, ganti dengan minmax(220px, 300px).

Satu catatan struktur: letakkan aside sebelum main di HTML bila pembaca ponsel memang perlu menemukan isi sidebar lebih dulu; urutan tampilan di ponsel mengikuti urutan penulisan.

Card Grid dengan auto-fit dan minmax #

Untuk sekumpulan kartu, media query per breakpoint tidak diperlukan sama sekali — biarkan grid menghitung:

css
.kartu-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 12px;
}

Baris repeat(auto-fit, minmax(180px, 1fr)) berbunyi: buat kolom selebar minimal 180px sebanyak mungkin yang muat, lalu bagi sisa ruang sama rata. Pada ruang konten 600px, tiga kolom 180px + dua gap 12px = 564px masih muat (empat kolom tidak), sehingga sisa 36px dibagi tiga dan setiap kartu menjadi 192px. Persempit ruang menjadi 380px dan grid otomatis turun ke dua kolom — tanpa satu pun @media. Perbedaan auto-fit dengan auto-fill serta variasi pola lainnya telah kita bedah pada Chapter auto-fit dan auto-fill .

Variasi yang sering menyusul adalah pola holy grail — header di atas, sidebar di samping, dan footer menutup bawah. Pola ini memakai named areas: grid-template-areas menyusun "header header" lalu "sidebar main" di desktop, dan cukup didefinisikan ulang satu kali di dalam media query untuk menumpuk seluruh area di ponsel. Karena area bernama hanya mengatur penempatan, perubahan responsifnya tetap berupa satu blok deklarasi yang ringkas — mekanisme lengkapnya telah kita bahas pada Chapter grid-lines dan areas .

Menyatukan Keduanya dalam Satu Halaman #

Demo chapter ini menaruh card grid di dalam area konten utama, sehingga keduanya saling berinteraksi: saat halaman melewati 1024px, sidebar masuk ke kiri dan ruang konten menyusut, lalu card grid menghitung ulang jumlah kolomnya terhadap ruang yang baru. Perubahan besar ditangani media query (posisi sidebar), sedangkan penyesuaian halus ditangani mekanisme fluid (auto-fit) — pembagian kerja inilah pola yang sebaiknya kita bawa ke proyek nyata.

Hasil di Browser:

text
Viewport harness 1280x720 (halaman 900px, mode desktop):
- .sidebar      -> width 260px  (kolom tetap kiri)
- .konten-utama -> width 624px  (900 - 260 - 16 gap)
- .kartu pertama -> width 192px (3 kolom pada ruang 600px)
Bila viewport di bawah 1024px, sidebar turun menumpuk di atas konten dan
card grid menghitung ulang kolomnya terhadap lebar penuh.

Layout yang tampil benar di banyak ukuran masih perlu dibuktikan satu per satu: ukur demo ini pada 360px, 768px, 1024px, dan 1280px untuk melihat empat keadaan yang benar-benar berbeda. Chapter berikutnya, sekaligus penutup section ini, membahas cara mengujinya secara sistematis di browser.