Web Development

CSS Grid Advanced: Grid Areas, Subgrid & Named Lines

Kuasai CSS Grid tingkat lanjut β€” template areas, subgrid, named lines, auto-fit/auto-fill, implicit/explicit grid, alignment, dan pola layout kompleks untuk membangun web modern yang responsif

1. Pengenalan CSS Grid Advanced

CSS Grid Layout adalah sistem layout dua dimensi yang powerful untuk membangun layout web kompleks. Di artikel ini, kita akan membahas fitur-fitur lanjutan CSS Grid yang jarang diketahui tetapi sangat berguna untuk membangun layout yang fleksibel, responsif, dan elegan.

Sebelum lanjut, pastikan kamu sudah memahami dasar CSS Grid seperti display: grid, grid-template-columns, grid-template-rows, dan grid-gap. Artikel ini akan fokus pada fitur tingkat lanjut.

Ringkasan Properti CSS Grid

Properti (Container) Properti (Item) Fungsi
grid-template-columnsgrid-columnDefinisikan kolom / posisi kolom item
grid-template-rowsgrid-rowDefinisikan baris / posisi baris item
grid-template-areasgrid-areaDefinisikan area bernama
grid-auto-flowβ€”Kontrol alur auto-placement
grid-auto-rowsβ€”Ukuran baris implicit
grid-auto-columnsβ€”Ukuran kolom implicit
gapβ€”Jarak antar item
justify-itemsjustify-selfAlignment horizontal item
align-itemsalign-selfAlignment vertikal item
justify-contentβ€”Distribusi konten horizontal
align-contentβ€”Distribusi konten vertikal
Diagram: Sistem Grid CSS
  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
  β”‚                     GRID CONTAINER                          β”‚
  β”‚  β”Œβ”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”        β”‚
  β”‚  β”‚     β”‚     β”‚     β”‚     β”‚     β”‚     β”‚     β”‚     β”‚  ←Line  β”‚
  β”‚  β”‚  1  β”‚  2  β”‚  3  β”‚  4  β”‚  5  β”‚  6  β”‚  7  β”‚  8  β”‚  Numberβ”‚
  β”‚  β”œβ”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€        β”‚
  β”‚  β”‚     β”‚           β”‚     β”‚           β”‚     β”‚     β”‚        β”‚
  β”‚  β”‚     β”‚   SPAN    β”‚     β”‚   SPAN    β”‚     β”‚     β”‚        β”‚
  β”‚  β”‚     β”‚   2 COL   β”‚     β”‚   2 COL   β”‚     β”‚     β”‚        β”‚
  β”‚  β”œβ”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€        β”‚
  β”‚  β”‚     β”‚           β”‚     β”‚           β”‚     β”‚     β”‚        β”‚
  β”‚  β””β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”˜        β”‚
  β”‚                                                             β”‚
  β”‚  ← Grid Lines bernama: [start] [content-start] [end] β†’     β”‚
  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

2. Explicit vs Implicit Grid

Memahami perbedaan antara explicit grid dan implicit grid sangat penting untuk mengontrol layout dengan tepat.

Explicit Grid

Explicit grid adalah grid yang kamu definisikan secara eksplisit menggunakan grid-template-columns, grid-template-rows, dan grid-template-areas.

.container {
  display: grid;
  /* Explicit: 3 kolom dengan ukuran tertentu */
  grid-template-columns: 200px 1fr 200px;
  /* Explicit: 2 baris */
  grid-template-rows: 80px auto;
}

/* Grid ini punya 3 kolom Γ— 2 baris = 6 sel explicit */

Implicit Grid

Implicit grid tercipta otomatis saat item ditempatkan di luar explicit grid. Browser membuat track baru secara otomatis.

.container {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  /* Hanya definisikan 2 baris */
  grid-template-rows: 100px 100px;

  /* Kontrol ukuran baris implicit (yang tercipta otomatis) */
  grid-auto-rows: 150px;
  /* Atau dengan minmax */
  grid-auto-rows: minmax(100px, auto);
  /* Kontrol ukuran kolom implicit */
  grid-auto-columns: 200px;
  /* Kontrol arah auto-placement */
  grid-auto-flow: row;       /* default: isi per baris */
  /* grid-auto-flow: column;    isi per kolom */
  /* grid-auto-flow: dense;     mengisi "lubang" kosong */
}

<!-- Jika ada 8 item, tapi grid hanya 3 kolom Γ— 2 baris = 6 sel,
     2 item sisa ditempatkan di baris implicit baru -->
<div class="container">
  <div>1</div> <div>2</div> <div>3</div>
  <div>4</div> <div>5</div> <div>6</div>
  <div>7</div> <div>8</div> <!-- Baris implicit! -->
</div>

grid-auto-flow: dense

.masonry-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-auto-rows: 100px;
  grid-auto-flow: dense;  /* Mengisi celah kosong */
}

/* Item yang span 2 kolom */
.wide { grid-column: span 2; }
/* Item yang span 2 baris */
.tall { grid-row: span 2; }

<!-- Dengan dense, item kecil akan "mengisi" celah
     yang ditinggalkan oleh item besar -->
<div class="masonry-grid">
  <div class="wide">A (2 kolom)</div>
  <div>B</div>      <!-- Bisa naik ke kolom sisa A -->
  <div class="tall">C (2 baris)</div>
  <div>D</div>
  <div>E</div>
</div>

3. Grid Template Areas

grid-template-areas memungkinkan kamu mendefinisikan layout menggunakan "peta ASCII" yang sangat intuitif. Ini adalah salah satu fitur terbaik dari CSS Grid.

Dasar Grid Template Areas

.layout {
  display: grid;
  grid-template-columns: 250px 1fr 200px;
  grid-template-rows: auto 1fr auto;
  grid-template-areas:
    "header  header  header"
    "sidebar content aside"
    "footer  footer  footer";
  gap: 16px;
  min-height: 100vh;
}

.header  { grid-area: header; }
.sidebar { grid-area: sidebar; }
.content { grid-area: content; }
.aside   { grid-area: aside; }
.footer  { grid-area: footer; }

<div class="layout">
  <header class="header">Header</header>
  <aside class="sidebar">Sidebar</aside>
  <main class="content">Konten Utama</main>
  <aside class="aside">Aside</aside>
  <footer class="footer">Footer</footer>
</div>
Diagram: Layout Grid Areas
  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
  β”‚              HEADER                      β”‚
  β”‚         (span 3 kolom)                   β”‚
  β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
  β”‚          β”‚                 β”‚             β”‚
  β”‚ SIDEBAR  β”‚    CONTENT      β”‚   ASIDE     β”‚
  β”‚  250px   β”‚     1fr         β”‚   200px     β”‚
  β”‚          β”‚                 β”‚             β”‚
  β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
  β”‚              FOOTER                      β”‚
  β”‚         (span 3 kolom)                   β”‚
  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Grid Areas Responsif

.layout {
  display: grid;
  grid-template-areas:
    "header  header"
    "sidebar content"
    "footer  footer";
  grid-template-columns: 200px 1fr;
  gap: 16px;
}

@media (max-width: 768px) {
  .layout {
    grid-template-areas:
      "header"
      "content"
      "sidebar"
      "footer";
    grid-template-columns: 1fr;
  }
}

/* Gunakan . (titik) untuk sel kosong */
.layout-sparse {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  grid-template-rows: auto auto;
  grid-template-areas:
    "hero   hero   hero"
    ".      cta    .";
}

.hero { grid-area: hero; }
.cta  { grid-area: cta; }

Named Areas yang Reusable

/* Card layout dengan grid areas */
.card {
  display: grid;
  grid-template-columns: auto 1fr;
  grid-template-rows: auto 1fr auto;
  grid-template-areas:
    "img title"
    "img desc"
    "img footer";
  gap: 12px;
}

.card-image    { grid-area: img; }
.card-title    { grid-area: title; }
.card-desc     { grid-area: desc; }
.card-footer   { grid-area: footer; }

/* Card tanpa gambar */
.card--text-only {
  grid-template-areas:
    "title"
    "desc"
    "footer";
  grid-template-columns: 1fr;
}

/* Dashboard widget layout */
.dashboard {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-template-rows: auto auto auto;
  grid-template-areas:
    "stats   stats   stats   stats"
    "chart   chart   table   table"
    "actions actions notif   notif";
  gap: 20px;
}

.stats   { grid-area: stats; }
.chart   { grid-area: chart; }
.table   { grid-area: table; }
.actions { grid-area: actions; }
.notif   { grid-area: notif; }

4. Named Lines & Named Areas

Selain named areas, kamu juga bisa memberi nama pada grid lines. Ini sangat powerful untuk layout yang lebih kompleks dan presisi.

Menamai Grid Lines

.container {
  display: grid;
  /* Named lines dengan bracket notation */
  grid-template-columns:
    [full-start] minmax(1em, 1fr)
    [main-start] minmax(0, 800px)
    [main-end]   minmax(1em, 1fr)
    [full-end];

  grid-template-rows:
    [header-start] auto
    [header-end content-start] 1fr
    [content-end footer-start] auto
    [footer-end];
}

/* Menggunakan named lines untuk positioning */
.header {
  grid-column: full-start / full-end;
  grid-row: header-start / header-end;
}

.main-content {
  grid-column: main-start / main-end;
  grid-row: content-start / content-end;
}

.sidebar {
  grid-column: full-start / main-start;
  grid-row: content-start / content-end;
}

.aside-right {
  grid-column: main-end / full-end;
  grid-row: content-start / content-end;
}

.footer {
  grid-column: full-start / full-end;
  grid-row: footer-start / footer-end;
}

Multiple Named Lines

/* Kolom dengan nama yang sama (untuk repeat) */
.container {
  display: grid;
  grid-template-columns: repeat(6, [col-start] 1fr [col-end]);
  /* Menghasilkan: col-start 1, col-end 1, col-start 2, ... */
}

/* Item menempati kolom tertentu berdasarkan nama */
.item {
  /* Dari col-start kecolom ke-2 sampai col-end kolom ke-4 */
  grid-column: col-start 2 / col-end 4;
}

/* span dengan named lines */
.item-wide {
  grid-column: col-start 1 / span 3;  /* 3 kolom dari kolom 1 */
}

/* Named lines dengan repeat() */
.bento-grid {
  display: grid;
  grid-template-columns:
    repeat(3, [gutter-start] minmax(0, 1fr) [gutter-end]);
  grid-auto-rows: minmax(150px, auto);
  gap: 20px;
}
πŸ’‘ Tips Named Lines

Kamu bisa memberi beberapa nama pada satu line dengan spasi: [main-start content-start] 1fr [main-end content-end]. Ini berguna saat satu line digunakan untuk berbagai referensi.

5. auto-fit vs auto-fill

auto-fit dan auto-fill adalah keyword yang digunakan dengan repeat() untuk membuat kolom (atau baris) yang otomatis menyesuaikan jumlahnya berdasarkan ruang yang tersedia. Perbedaannya halus tetapi penting.

auto-fill

/* auto-fill: Membuat sebanyak mungkin track, bahkan yang kosong */
.grid-auto-fill {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 16px;
}

/*
  Pada container 700px:
  β†’ 3 kolom Γ— 200px = 600px (sisanya dibagi rata)
  β†’ Track ke-4 tidak cukup, jadi 3 kolom
  
  auto-fill tetap membuat "slot kosong" meski item tidak ada.
  Jadi grid punya 3 kolom bahkan jika hanya ada 1 item.
*/

auto-fit

/* auto-fit: Mirip auto-fill, tapi track kosong di-collapse */
.grid-auto-fit {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 16px;
}

/*
  Pada container 700px dengan 1 item:
  β†’ auto-fit collapse track kosong
  β†’ 1 item mengambil seluruh lebar (memenuhi 3 track yang tersedia)
  
  auto-fit sangat bagus untuk responsive grid tanpa media query!
*/
Diagram: auto-fill vs auto-fit
  Container = 700px, Items = 2, minmax(200px, 1fr)

  AUTO-FILL (3 tracks, 1 kosong):
  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
  β”‚  Item 1  β”‚  Item 2  β”‚  (kosong)β”‚  ← Track 3 tetap ada
  β”‚  ~233px  β”‚  ~233px  β”‚  ~233px  β”‚
  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

  AUTO-FIT (2 tracks, mengisi penuh):
  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
  β”‚     Item 1       β”‚     Item 2       β”‚  ← Track kosong di-collapse
  β”‚     350px        β”‚     350px        β”‚
  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Pola Responsive dengan auto-fit

/* Responsive card grid TANPA media query */
.cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 24px;
}
/* 
  - Pada 1200px: 4 kolom (4 Γ— 280px = 1120px)
  - Pada 900px:  3 kolom (3 Γ— 280px = 840px)
  - Pada 600px:  2 kolom (2 Γ— 280px = 560px)
  - Pada 320px:  1 kolom (1 Γ— 280px)
*/

/* Product gallery dengan ukuran bervariasi */
.gallery {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  grid-auto-rows: 200px;
  gap: 8px;
}

/* Featured item span 2 kolom dan 2 baris */
.gallery-item--featured {
  grid-column: span 2;
  grid-row: span 2;
}

/* Image grid yang mempertahankan rasio aspek */
.image-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
  grid-auto-rows: 1fr;  /* Equal height rows */
  gap: 16px;
}

.image-grid img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

6. minmax(), fit-content(), min()

Fungsi-fungsi ini memberikan fleksibilitas luar biasa dalam mendefinisikan ukuran track grid.

minmax()

/* minmax(min, max) β€” batas bawah dan atas ukuran */
.container {
  display: grid;
  /* Kolom minimal 200px, maximal bisa tumbuh */
  grid-template-columns: repeat(3, minmax(200px, 1fr));
  /* Baris minimal 100px, maximal sesuai konten */
  grid-auto-rows: minmax(100px, auto);
}

/* Kolom dengan batas spesifik */
.content-grid {
  display: grid;
  grid-template-columns:
    minmax(200px, 250px)   /* Sidebar: min 200, max 250 */
    minmax(400px, 1fr)     /* Content: min 400, max fleksibel */
    minmax(150px, 200px);  /* Aside: min 150, max 200 */
}

fit-content()

/* fit-content(value) β€” seperti max-width pada track */
.card-grid {
  display: grid;
  /* Kolom selebar kontennya, tapi tidak lebih dari 300px */
  grid-template-columns: repeat(3, fit-content(300px));
  gap: 16px;
}

/* Center content dengan fit-content */
.centered-layout {
  display: grid;
  justify-content: center;
  /* Konten selebar isinya, max 700px */
  grid-template-columns: fit-content(700px);
}

/* Mixed: fixed + fit-content + auto */
.article-layout {
  display: grid;
  grid-template-columns:
    200px                    /* Sidebar: fixed */
    fit-content(800px)      /* Article: sesuai konten, max 800px */
    1fr;                    /* Aside: sisa ruang */
}

min(), max(), clamp()

/* min() β€” pilih nilai terkecil */
.grid-min {
  grid-template-columns:
    min(200px, 25%)  /* 200px atau 25%, mana yang lebih kecil */
    1fr;
}

/* clamp() β€” batasi nilai antara min dan max */
.grid-clamp {
  grid-template-columns:
    clamp(150px, 20%, 300px)  /* Min 150, ideal 20%, max 300 */
    1fr;
}

/* Gabungkan berbagai fungsi */
.advanced-grid {
  display: grid;
  grid-template-columns:
    minmax(min(200px, 20%), 300px)
    minmax(300px, 1fr)
    clamp(150px, 15vw, 250px);
  grid-auto-rows: clamp(80px, 10vh, 200px);
}

7. CSS Subgrid

Subgrid adalah fitur CSS Grid yang memungkinkan child grid menggunakan track dari parent grid-nya. Ini sangat berguna untuk menyelaraskan konten di dalam card atau komponen yang berbeda.

⚠️ Browser Support

Subgrid didukung di Firefox 71+, Safari 16+, dan Chrome 117+ (September 2023). Pastikan cek Can I Use sebelum menggunakannya di produksi.

Subgrid untuk Kolom

/* Parent grid */
.card-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 24px;
}

/* Card menggunakan subgrid dari parent */
.card {
  display: grid;
  /* Ikuti kolom parent, buat baris sendiri */
  grid-column: span 1;
  grid-template-rows: subgrid;
  /* Atau ikuti kolom parent */
  grid-template-columns: subgrid;
}

<div class="card-grid">
  <article class="card">
    <img src="photo.jpg" alt="Foto">
    <h3>Judul Card 1</h3>
    <p>Deskripsi singkat...</p>
    <button>Baca Selengkapnya</button>
  </article>
  <article class="card">
    <img src="photo2.jpg" alt="Foto">
    <h3>Judul yang Lebih Panjang dari Card Lain</h3>
    <p>Deskripsi...</p>
    <button>Baca</button>
  </article>
</div>
<!-- Semua card sejajar! Judul, deskripsi, dan button
     berada di baris yang sama meski konten berbeda panjang -->

Subgrid untuk Baris

.pricing-table {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: auto auto 1fr auto;
  gap: 0;
}

.pricing-card {
  display: grid;
  grid-row: span 4;
  grid-template-rows: subgrid;  /* Ikuti 4 baris parent */
  gap: 0;
  border: 1px solid #ddd;
  padding: 24px;
}

/* Semua card sejajar di setiap baris:
   Baris 1: Header (nama paket)
   Baris 2: Harga
   Baris 3: Fitur (stretch penuh)
   Baris 4: CTA Button */

<div class="pricing-table">
  <div class="pricing-card">
    <h3>Basic</h3>
    <p class="price">Rp 50.000/bln</p>
    <ul class="features">
      <li>5 GB Storage</li>
      <li>1 Domain</li>
    </ul>
    <button>Pilih Paket</button>
  </div>
  <div class="pricing-card">
    <h3>Pro</h3>
    <p class="price">Rp 150.000/bln</p>
    <ul class="features">
      <li>50 GB Storage</li>
      <li>Unlimited Domain</li>
      <li>SSL Certificate</li>
    </ul>
    <button>Pilih Paket</button>
  </div>
</div>

Subgrid: Column + Row

/* Complex dashboard layout dengan subgrid */
.dashboard {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-template-rows: auto repeat(3, 1fr) auto;
  gap: 16px;
  min-height: 100vh;
}

.widget {
  display: grid;
  grid-column: span 2;
  grid-row: span 2;
  grid-template-columns: subgrid;
  grid-template-rows: subgrid;
}

.widget-header  { grid-column: 1 / -1; grid-row: 1; }
.widget-content { grid-column: 1 / -1; grid-row: 2; }

8. Grid Alignment Mendalam

CSS Grid memiliki sistem alignment yang sangat lengkap dan powerful. Ada alignment untuk container, content, dan individual items.

Container Alignment

.grid {
  display: grid;
  grid-template-columns: repeat(3, 200px); /* Track lebih kecil dari container */
  grid-template-rows: repeat(2, 150px);

  /* justify-content: horizontal alignment of tracks */
  justify-content: start;      /* ← Kiri */
  justify-content: center;     /* ← Tengah */
  justify-content: end;        /* ← Kanan */
  justify-content: space-between;
  justify-content: space-around;
  justify-content: space-evenly;
  justify-content: stretch;    /* default */

  /* align-content: vertical alignment of tracks */
  align-content: start;
  align-content: center;
  align-content: end;
  align-content: space-between;
  align-content: stretch;     /* default */

  /* Shorthand */
  place-content: center center;    /* align-content justify-content */
}

Item Alignment

.grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);

  /* justify-items: alignment horizontal SEMUA item */
  justify-items: start;      /* ← Kiri */
  justify-items: center;     /* ← Tengah */
  justify-items: end;        /* ← Kanan */
  justify-items: stretch;    /* default: penuhi sel */

  /* align-items: alignment vertikal SEMUA item */
  align-items: start;
  align-items: center;
  align-items: end;
  align-items: stretch;      /* default */

  /* Shorthand */
  place-items: center center;   /* align-items justify-items */
}

/* Individual item override */
.special-item {
  justify-self: center;      /* Override horizontal */
  align-self: end;           /* Override vertikal */
  place-self: end center;    /* Shorthand */
}

Gap yang Granular

.grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 20px;                 /* row-gap dan column-gap sama */

  /* Atau beda */
  row-gap: 30px;
  column-gap: 16px;

  /* Shorthand */
  gap: 30px 16px;            /* row-gap column-gap */

  /* Gap dengan unit berbeda */
  gap: 1em 2vw;

  /* Persentase gap (dari kontainer) */
  gap: 2% 4%;
}

9. Pola Layout Populer

Berikut beberapa pola layout CSS Grid yang sering digunakan dalam pengembangan web profesional.

Holy Grail Layout

.holy-grail {
  display: grid;
  grid-template-columns: 200px 1fr 200px;
  grid-template-rows: auto 1fr auto;
  grid-template-areas:
    "header header header"
    "nav    main   aside"
    "footer footer footer";
  min-height: 100vh;
  gap: 0;
}

@media (max-width: 768px) {
  .holy-grail {
    grid-template-columns: 1fr;
    grid-template-areas:
      "header"
      "main"
      "nav"
      "aside"
      "footer";
  }
}

Magazine / Editorial Layout

.magazine {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  grid-auto-rows: minmax(200px, auto);
  gap: 16px;
}

/* Featured article β€” full width */
.featured {
  grid-column: 1 / -1;
  grid-row: span 2;
}

/* Standard article β€” 2 kolom */
.article {
  grid-column: span 2;
}

/* Wide article β€” 3 kolom */
.article--wide {
  grid-column: span 3;
}

/* Sidebar article β€” 1 kolom */
.article--sidebar {
  grid-column: span 1;
}

/* Breaking news di tengah */
.breaking {
  grid-column: 2 / 6;
  grid-row: span 1;
}

@media (max-width: 768px) {
  .magazine {
    grid-template-columns: 1fr;
  }
  .featured,
  .article,
  .article--wide,
  .breaking {
    grid-column: 1 / -1;
  }
}

Bento Grid Layout

/* Bento grid ala Apple / Dashboard */
.bento {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-auto-rows: 200px;
  gap: 16px;
}

.bento-item:nth-child(1) {
  grid-column: span 2;
  grid-row: span 2;
}

.bento-item:nth-child(2) {
  grid-column: span 2;
}

.bento-item:nth-child(5) {
  grid-column: span 3;
}

.bento-item:nth-child(7) {
  grid-column: span 2;
  grid-row: span 2;
}

@media (max-width: 640px) {
  .bento {
    grid-template-columns: 1fr 1fr;
    grid-auto-rows: 160px;
  }
  .bento-item:nth-child(1),
  .bento-item:nth-child(5),
  .bento-item:nth-child(7) {
    grid-column: span 2;
    grid-row: span 1;
  }
}

Sidebar Layout yang Fleksibel

/* Sidebar dengan minimum dan maximum */
.page-layout {
  display: grid;
  grid-template-columns:
    minmax(200px, 250px)    /* Sidebar */
    minmax(0, 1fr)          /* Content */
    minmax(180px, 220px);   /* Aside */
  gap: 24px;
  max-width: 1400px;
  margin: 0 auto;
  padding: 0 24px;
}

/* Sidebar collapse pada mobile */
@media (max-width: 960px) {
  .page-layout {
    grid-template-columns: 1fr;
  }
  .sidebar { display: none; }
}

/* Sidebar jadi drawer pada tablet */
@media (min-width: 641px) and (max-width: 959px) {
  .page-layout {
    grid-template-columns: minmax(0, 1fr);
  }
  .aside { display: none; }
}

10. Responsive Grid Tanpa Media Query

Salah satu kekuatan terbesar CSS Grid adalah bisa membuat layout responsif tanpa media query sama sekali, menggunakan auto-fit, minmax(), dan clamp().

Pattern: Responsive Card Grid

/* RESPONSIVE TANPA MEDIA QUERY! */
.auto-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(250px, 100%), 1fr));
  gap: clamp(16px, 2vw, 32px);
  padding: clamp(16px, 4vw, 48px);
}

/*
  min(250px, 100%) memastikan card tidak overflow pada mobile.
  clamp() memberikan padding dan gap yang smooth.
  
  Hasil:
  - Layar > 1000px: 4 kolom
  - Layar 750-1000px: 3 kolom
  - Layar 500-750px: 2 kolom
  - Layar < 500px: 1 kolom
*/

Pattern: Container-Like Grid

/* Grid yang centering konten secara responsif */
.content-grid {
  display: grid;
  grid-template-columns:
    [full-start] minmax(1em, 1fr)
    [content-start] minmax(0, 70ch)
    [content-end] minmax(1em, 1fr)
    [full-end];
}

/* Konten utama di content area */
.content-grid > * {
  grid-column: content-start / content-end;
}

/* Breakout: gambar/video yang melebihi content width */
.breakout {
  grid-column: full-start / full-end;
}

/* Half-breakout: melebar sedikit */
.half-breakout {
  grid-column: content-start / full-end;
}

Pattern: Sidebar yang Responsif

/* Sidebar yang wrap ke bawah pada mobile */
.layout-sidebar {
  display: grid;
  grid-template-columns: 1fr min(65ch, 100%) 1fr;
  gap: 0;
}

.layout-sidebar > * {
  grid-column: 2;
}

.full-bleed {
  grid-column: 1 / -1;
}

/* Dengan subgrid untuk alignment yang tepat */
.layout-sidebar > .sidebar {
  grid-column: 3;
  display: grid;
  grid-template-columns: subgrid;
}

11. Quiz Pemahaman

Uji pemahamanmu tentang CSS Grid Advanced dengan menjawab pertanyaan berikut:

Pertanyaan 1: Apa perbedaan utama antara auto-fill dan auto-fit?

a) auto-fill membuat track kosong tetap ada, auto-fit collapse track kosong
b) auto-fill hanya untuk kolom, auto-fit hanya untuk baris
c) auto-fill lebih cepat render daripada auto-fit
d) Tidak ada perbedaan, keduanya sama

Pertanyaan 2: Apa fungsi dari grid-auto-flow: dense?

a) Membuat grid lebih padat dengan mengurangi gap
b) Mengisi celah kosong dengan item yang lebih kecil
c) Membuat semua item memiliki ukuran yang sama
d) Mengatur urutan item secara terbalik

Pertanyaan 3: Untuk menyelaraskan konten card di baris yang sama meski tinggi konten berbeda, properti apa yang digunakan?

a) align-items: stretch
b) grid-template-rows: subgrid
c) justify-content: center
d) grid-auto-rows: auto

Pertanyaan 4: Kode grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)) pada container 800px akan menghasilkan berapa kolom?

a) 2 kolom
b) 3 kolom
c) 4 kolom
d) 800/250 = 3.2, jadi 3 kolom

Pertanyaan 5: Apa yang dilakukan oleh grid-column: 1 / -1?

a) Item ditempatkan di kolom pertama saja
b) Item memenuhi semua kolom (full width)
c) Item ditempatkan di kolom terakhir
d) Item dihapus dari grid
πŸ” Zoom
100%
🎨 Tema