HTML Dasar #34 - Menggunakan Grid CSS untuk Layout Halaman

Setelah kita belajar Flexbox untuk layout satu dimensi (baris ATAU kolom), sekarang saatnya mengenal CSS Grid - alat yang lebih powerful untuk layout dua dimensi (baris DAN kolom sekaligus). Grid adalah solusi terbaik untuk membuat layout halaman secara keseluruhan!


Apa Itu CSS Grid?

CSS Grid Layout adalah sistem layout dua dimensi yang memungkinkan kita mengatur elemen dalam baris dan kolom secara bersamaan. Bayangkan seperti tabel tapi dengan fleksibilitas CSS penuh.

Flexbox vs Grid:
- Flexbox → 1 dimensi (baik untuk navbar, card grid, form layout)
- Grid → 2 dimensi (baik untuk layout halaman utuh, dashboard, galeri foto)

Bukan "salah satu lebih baik" - keduanya saling melengkapi!

Konsep Dasar CSS Grid

Grid memiliki beberapa komponen penting:

Komponen Penjelasan Contoh
Grid Container (induk) Elemen dengan display: grid <div class="grid-container">
Grid Item (anak) Elemen langsung di dalam grid container <div>Item 1</div>
Grid Line (garis) Garis pemisah antara baris/kolom Garis vertikal/horizontal
Grid Track (jalur) Ruang antara dua grid line (baris/kolom) Satu baris atau satu kolom
Grid Cell (sel) Perpotongan antara satu baris dan satu kolom Satu kotak dalam grid
Grid Area (area) Kumpulan sel yang membentuk area persegi panjang Header, sidebar, konten utama

1. Membuat Grid Sederhana (display: grid)

Cukup tambahkan display: grid ke container, lalu tentukan jumlah kolom dengan grid-template-columns.

Contoh Dasar 3 Kolom:

<style>
    .grid-sederhana {
        display: grid;
        grid-template-columns: 100px 200px 100px;
        gap: 10px;
        background: #f0f4f8;
        padding: 10px;
    }
    .grid-sederhana div {
        background: #3b82f6;
        color: white;
        padding: 20px;
        text-align: center;
        border-radius: 8px;
    }
</style>

<div class="grid-sederhana">
    <div>100px</div>
    <div>200px</div>
    <div>100px</div>
</div>
100px
200px
100px

3 kolom dengan lebar berbeda: 100px, 200px, 100px

2. Unit Flexibel untuk Grid (fr)

Unit fr (fraction) adalah unit khusus Grid untuk membagi ruang yang tersedia. Ini sangat powerful untuk layout responsif.

Contoh dengan fr:

<style>
    .grid-fr {
        display: grid;
        grid-template-columns: 1fr 2fr 1fr;
        gap: 10px;
        background: #f0f4f8;
        padding: 10px;
    }
</style>

<div class="grid-fr">
    <div>1fr</div>
    <div>2fr</div>
    <div>1fr</div>
</div>
1fr
2fr
1fr

Kolom tengah 2x lebih lebar dari kolom samping (responsif)

3. repeat() dan minmax()

Fungsi repeat() memudahkan membuat banyak kolom/baris dengan pola yang sama. minmax() menentukan ukuran minimal dan maksimal.

Contoh repeat:

<style>
    .grid-repeat {
        display: grid;
        grid-template-columns: repeat(4, 1fr);
        gap: 10px;
    }
    .grid-minmax {
        display: grid;
        grid-template-columns: repeat(3, minmax(150px, 1fr));
        gap: 10px;
        margin-top: 20px;
    }
</style>

repeat(4, 1fr) → 4 kolom sama lebar:

1
2
3
4

minmax(150px, 1fr) → minimal 150px, maksimal 1fr:

min 150px
min 150px
min 150px

4. grid-template-rows (Mengatur Baris)

grid-template-rows mengatur tinggi setiap baris.

<style>
    .grid-rows {
        display: grid;
        grid-template-columns: 1fr 1fr;
        grid-template-rows: 100px 200px 100px;
        gap: 10px;
    }
</style>
Baris 1
Baris 1
Baris 2 (150px)
Baris 2 (150px)
Baris 3
Baris 3

Baris 1: 80px | Baris 2: 150px | Baris 3: 80px

5. gap (Jarak Antar Baris dan Kolom)

gap, row-gap, dan column-gap mengatur jarak antar sel grid.

<style>
    .grid-gap {
        display: grid;
        grid-template-columns: repeat(3, 1fr);
        gap: 20px 10px;  /* row-gap: 20px, column-gap: 10px */
        /* atau: row-gap: 20px; column-gap: 10px; */
    }
</style>
1
2
3
4
5
6

gap: 20px (baris) dan 10px (kolom)

6. grid-template-areas (Layout dengan Nama Area)

grid-template-areas adalah fitur paling intuitif dari Grid. Kita bisa memberi nama pada setiap area, lalu menyusunnya seperti denah.

Contoh Layout Website Standar:

<style>
    .website-layout {
        display: grid;
        grid-template-areas: 
            "header header header"
            "sidebar main main"
            "footer footer footer";
        grid-template-columns: 250px 1fr 1fr;
        grid-template-rows: auto 1fr auto;
        gap: 15px;
        min-height: 100vh;
    }
    .header { grid-area: header; background: #3b82f6; color: white; padding: 20px; }
    .sidebar { grid-area: sidebar; background: #f0f4f8; padding: 20px; }
    .main { grid-area: main; background: white; padding: 20px; box-shadow: 0 2px 5px rgba(0,0,0,0.1); }
    .footer { grid-area: footer; background: #1e293b; color: white; padding: 20px; text-align: center; }
</style>

<div class="website-layout">
    <div class="header">Header</div>
    <div class="sidebar">Sidebar</div>
    <div class="main">Main Content</div>
    <div class="footer">Footer</div>
</div>
Header
Sidebar
Main Content
Footer

Layout website dengan grid-template-areas: Header | Sidebar + Main | Footer

Keuntungan grid-template-areas:
  • Layout terlihat seperti denah (mudah dibaca)
  • Mudah mengatur ulang posisi tanpa mengubah HTML
  • Responsif: cukup ubah grid-template-areas di media query
  • Cocok untuk layout halaman secara keseluruhan

7. Positioning Item dengan grid-column dan grid-row

Kita bisa menentukan posisi item secara spesifik menggunakan grid-column dan grid-row.

<style>
    .grid-position {
        display: grid;
        grid-template-columns: repeat(4, 1fr);
        grid-template-rows: repeat(3, 100px);
        gap: 10px;
    }
    .item1 { grid-column: 1 / 3; background: #3b82f6; }  /* dari kolom 1 ke 3 */
    .item2 { grid-column: 3 / 5; background: #22c55e; }  /* dari kolom 3 ke 5 */
    .item3 { grid-column: 1 / 2; background: #f59e0b; }
    .item4 { grid-column: 2 / 5; background: #ef4444; }
</style>
kolom 1-3
kolom 3-5
kolom 1
kolom 2-5

Item bisa menggabungkan beberapa kolom menggunakan grid-column

Contoh Proyek: Layout Dashboard Responsif

Berikut contoh dashboard lengkap dengan Grid yang responsif:

<!DOCTYPE html>
<html lang="id">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Dashboard dengan CSS Grid</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            background: #f0f4f8;
        }
        .dashboard {
            display: grid;
            grid-template-areas: 
                "sidebar header"
                "sidebar stats"
                "sidebar charts"
                "sidebar recent";
            grid-template-columns: 260px 1fr;
            grid-template-rows: auto auto auto 1fr;
            min-height: 100vh;
        }
        .sidebar {
            grid-area: sidebar;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            padding: 25px;
        }
        .sidebar h2 {
            margin-bottom: 30px;
            font-size: 24px;
        }
        .sidebar nav a {
            display: block;
            color: rgba(255,255,255,0.8);
            text-decoration: none;
            padding: 12px 15px;
            margin: 5px 0;
            border-radius: 8px;
            transition: all 0.2s;
        }
        .sidebar nav a:hover {
            background: rgba(255,255,255,0.2);
            color: white;
        }
        .header {
            grid-area: header;
            background: white;
            padding: 20px 25px;
            display: flex;
            justify-content: space-between;
            align-items: center;
            box-shadow: 0 2px 5px rgba(0,0,0,0.05);
        }
        .stats {
            grid-area: stats;
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
            gap: 20px;
            padding: 25px;
        }
        .stat-card {
            background: white;
            padding: 20px;
            border-radius: 12px;
            box-shadow: 0 2px 5px rgba(0,0,0,0.05);
        }
        .stat-card h3 {
            color: #64748b;
            font-size: 14px;
            margin-bottom: 10px;
        }
        .stat-card .number {
            font-size: 32px;
            font-weight: bold;
            color: #1e293b;
        }
        .charts {
            grid-area: charts;
            background: white;
            margin: 0 25px 25px 25px;
            padding: 20px;
            border-radius: 12px;
            box-shadow: 0 2px 5px rgba(0,0,0,0.05);
        }
        .recent {
            grid-area: recent;
            background: white;
            margin: 0 25px 25px 25px;
            padding: 20px;
            border-radius: 12px;
            box-shadow: 0 2px 5px rgba(0,0,0,0.05);
        }
        .recent table {
            width: 100%;
            border-collapse: collapse;
            margin-top: 15px;
        }
        .recent th, .recent td {
            padding: 12px;
            text-align: left;
            border-bottom: 1px solid #e2e8f0;
        }
        .recent th {
            color: #64748b;
            font-weight: normal;
        }
        @media (max-width: 768px) {
            .dashboard {
                grid-template-areas: 
                    "header"
                    "stats"
                    "charts"
                    "recent";
                grid-template-columns: 1fr;
            }
            .sidebar {
                display: none;
            }
            .stats {
                grid-template-columns: 1fr;
            }
        }
        .info {
            background: #eef2ff;
            padding: 20px;
            margin: 20px;
            border-radius: 12px;
        }
    </style>
</head>
<body>

    <div class="dashboard">
        <aside class="sidebar">
            <h2>MyDashboard</h2>
            <nav>
                <a href="#">Home</a>
                <a href="#">Analytics</a>
                <a href="#">Settings</a>
                <a href="#">Profile</a>
            </nav>
        </aside>
        
        <header class="header">
            <h1>Dashboard</h1>
            <div>Welcome, User!</div>
        </header>
        
        <div class="stats">
            <div class="stat-card"><h3>Total Users</h3><div class="number">12,345</div></div>
            <div class="stat-card"><h3>Revenue</h3><div class="number">$45,678</div></div>
            <div class="stat-card"><h3>Orders</h3><div class="number">1,234</div></div>
        </div>
        
        <div class="charts">
            <h3>Chart Area</h3>
            <p>Grafik performa akan ditampilkan di sini.</p>
        </div>
        
        <div class="recent">
            <h3>Recent Orders</h3>
            <table>
                <tr><th>Order ID</th><th>Customer</th><th>Amount</th></tr>
                <tr><td>#001</td><td>Budi</td><td>$100</td></tr>
                <tr><td>#002</td><td>Ani</td><td>$250</td></tr>
                <tr><td>#003</td><td>Citra</td><td>$75</td></tr>
            </table>
        </div>
    </div>
    
    <div class="info">
        <strong>CSS Grid Properties yang Digunakan:</strong>
        <ul>
            <li><code>display: grid</code> - mengaktifkan grid</li>
            <li><code>grid-template-areas</code> - layout dengan nama area</li>
            <li><code>grid-template-columns</code> - lebar kolom (260px dan 1fr)</li>
            <li><code>grid-template-rows</code> - tinggi baris (auto, auto, auto, 1fr)</li>
            <li><code>repeat(auto-fit, minmax(200px, 1fr))</code> - stats card responsif</li>
            <li>Media query untuk mengubah layout di HP</li>
        </ul>
    </div>

</body>
</html>

Hasil visual dashboard:

MyDashboard

Dashboard

Welcome, User!
Total Users
12,345
Revenue
$45,678
Orders
1,234

Chart Area

Grafik performa akan ditampilkan di sini.

Grid vs Flexbox - Kapan Menggunakan?

Skenario Rekomendasi Alasan
Layout halaman (header, sidebar, main, footer) Grid 2 dimensi (baris dan kolom)
Navbar (logo kiri, menu kanan) Flexbox 1 dimensi, lebih sederhana
Galeri foto (grid card) Grid Mudah mengatur baris dan kolom
Card container (responsif) Flexbox atau Grid Keduanya bisa, pilih sesuai kebutuhan
Form layout (label + input) Grid Mudah menyelaraskan label dan input
Memusatkan elemen di tengah Flexbox justify-content + align-items center
Tips Memilih:
  • Jika hanya butuh mengatur satu arah (horizontal ATAU vertikal) → Flexbox
  • Jika butuh mengatur dua arah (horizontal DAN vertikal) → Grid
  • Gunakan Grid untuk layout halaman (kerangka besar)
  • Gunakan Flexbox untuk komponen kecil (navbar, card, form)
  • Keduanya bisa digabung dalam satu halaman!

Kesalahan Umum Pemula

  • Lupa menambahkan display: grid ke container → Properti grid lainnya tidak akan berfungsi.
  • Mencoba menggunakan fr di luar gridfr hanya bekerja di grid-template-columns/rows.
  • Lupa bahwa grid-template-areas harus berbentuk persegi panjang → Area tidak bisa berbentuk L atau T.
  • Menggunakan spasi yang tidak konsisten di grid-template-areas → Setiap baris harus memiliki jumlah kolom yang sama.
  • Mengira Grid menggantikan Flexbox → Mereka saling melengkapi, bukan menggantikan.
Debugging Tips:
  • Buka Developer Tools (F12) → inspect elemen → lihat tab Layout (di Firefox) untuk visualisasi grid
  • Di Chrome, inspect elemen grid → klik badge "grid" untuk menampilkan garis grid
  • Gunakan CSS Grid Inspector untuk melihat nomor garis grid

Latihan Singkat

  1. Buat file HTML baru dengan judul "Latihan CSS Grid"
  2. Buat grid dengan 3 kolom (1fr, 2fr, 1fr) dan 2 baris (100px, auto)
  3. Isi dengan 6 item
  4. Buat layout website sederhana dengan grid-template-areas: header, sidebar, main, footer
  5. Buat galeri foto dengan repeat(4, 1fr) dan gap: 15px
  6. Uji responsive dengan media query (ubah jumlah kolom di HP)

Intisari Hari Ini

  • display: grid → mengaktifkan grid pada container
  • grid-template-columns dan grid-template-rows → menentukan jumlah dan ukuran kolom/baris
  • fr → unit fleksibel untuk membagi ruang
  • repeat() → membuat banyak kolom/baris dengan pola yang sama
  • minmax() → menentukan ukuran minimal dan maksimal
  • gap → jarak antar baris dan kolom
  • grid-template-areas → layout dengan nama area (sangat intuitif)
  • Grid untuk layout 2 dimensi, Flexbox untuk 1 dimensi
Tantangan Akhir Pekan: Buat sebuah Halaman Galeri Foto/Portofolio yang menggunakan CSS Grid untuk layout! Persyaratan:
  • Grid galeri dengan minimal 9 gambar (placeholder boleh pakai warna atau gambar dummy)
  • Gunakan repeat(auto-fit, minmax(250px, 1fr)) untuk membuat galeri responsif
  • Salah satu gambar (gambar utama) berukuran 2x lebar dan 2x tinggi (gunakan grid-column dan grid-row)
  • Tambahkan overlay teks saat hover (nama project)
  • Layout halaman menggunakan grid-template-areas: header, galeri, footer
  • Responsive: di HP, semua gambar jadi 1 kolom, gambar utama kembali ke ukuran normal
  • Tambahkan kotak penjelasan yang mendokumentasikan semua properti grid yang digunakan

Bonus: Gunakan CSS Grid dan Flexbox bersamaan (grid untuk layout halaman, flex untuk card di dalamnya).

Selamat mencoba!

Artikel Sebelumnya: HTML Dasar #33 - Menggunakan Flexbox untuk Layout (display: flex)
Artikel Selanjutnya: HTML Dasar #35 - Media Query: Membuat Tampilan Berubah di HP, Tablet, PC

Lebih baru Lebih lama

نموذج الاتصال