CSS Dasar #26 - flex-wrap, flex-flow, dan gap

Setelah mempelajari perataan dengan justify-content dan align-items, sekarang saatnya memahami properti yang mengatur bagaimana item flex berperilaku saat tidak muat dalam satu baris. Properti flex-wrap, flex-flow (shorthand), dan gap sangat penting untuk membuat layout yang responsif dan rapi.


1. flex-wrap (Membungkus Item)

Secara default, semua flex item akan dipaksa berada dalam satu baris (no-wrap), meskipun melebihi lebar container. Properti flex-wrap mengatur apakah item boleh pindah ke baris baru ketika tidak muat.

Nilai flex-wrap:
- nowrap (default) → semua item dalam satu baris (bisa overflow).
- wrap → item pindah ke baris baru jika tidak muat.
- wrap-reverse → sama seperti wrap, tetapi baris baru di atas.

Contoh perbandingan:

<style>
    .container {
        display: flex;
        background: #f0f4f8;
        padding: 10px;
        width: 300px;
        margin-bottom: 15px;
    }
    .item {
        background: #3b82f6;
        color: white;
        padding: 15px;
        width: 100px;
        text-align: center;
        margin: 5px;
    }
    .nowrap { flex-wrap: nowrap; }
    .wrap { flex-wrap: wrap; }
    .wrap-reverse { flex-wrap: wrap-reverse; }
</style>

<div class="container nowrap">
    <div class="item">1</div><div class="item">2</div><div class="item">3</div>
</div>
<div class="container wrap">
    <div class="item">1</div><div class="item">2</div><div class="item">3</div>
</div>
<div class="container wrap-reverse">
    <div class="item">1</div><div class="item">2</div><div class="item">3</div>
</div>

nowrap (default) - item dipaksa satu baris, overflow

1
2
3

wrap - item pindah ke baris baru

1
2
3

wrap-reverse - baris baru di atas

1
2
3

Perhatikan perbedaan posisi baris pada wrap dan wrap-reverse.

2. flex-flow (Shorthand)

flex-flow adalah properti shorthand yang menggabungkan flex-direction dan flex-wrap dalam satu baris.

Sintaks:

flex-flow: flex-direction flex-wrap;

Contoh:

<style>
    .flex-flow-row-wrap {
        display: flex;
        flex-flow: row wrap;
        background: #f0f4f8;
        padding: 10px;
        width: 300px;
    }
    .flex-flow-column-wrap {
        display: flex;
        flex-flow: column wrap;
        background: #f0f4f8;
        padding: 10px;
        height: 200px;
    }
    .item {
        background: #3b82f6;
        color: white;
        padding: 10px;
        width: 80px;
        margin: 5px;
        text-align: center;
    }
</style>

<div class="flex-flow-row-wrap">
    <div class="item">1</div><div class="item">2</div><div class="item">3</div><div class="item">4</div>
</div>

flex-flow: row wrap

1
2
3
4

flex-flow: column wrap (vertical wrap)

1
2
3
4
Keuntungan flex-flow: Menulis kode lebih singkat, menggabungkan arah dan pembungkusan dalam satu properti.

3. gap (Jarak Antar Item)

Properti gap (atau row-gap dan column-gap) digunakan untuk mengatur jarak langsung antar item flex (dan grid). Ini lebih praktis daripada menggunakan margin pada item.

Sintaks:

gap: row-gap column-gap;
/* Contoh: gap: 20px; (baris dan kolom sama) */
/* gap: 20px 10px; (row 20px, column 10px) */

Contoh:

<style>
    .flex-gap {
        display: flex;
        flex-wrap: wrap;
        gap: 20px;
        background: #f0f4f8;
        padding: 15px;
    }
    .flex-gap-item {
        background: #3b82f6;
        color: white;
        padding: 20px;
        width: 120px;
        text-align: center;
    }
</style>

<div class="flex-gap">
    <div class="flex-gap-item">1</div>
    <div class="flex-gap-item">2</div>
    <div class="flex-gap-item">3</div>
    <div class="flex-gap-item">4</div>
</div>
1
2
3
4

gap: 15px (jarak antar item, baik horizontal maupun vertikal)

Contoh Proyek: Galeri Responsif dengan flex-wrap dan gap

<!DOCTYPE html>
<html lang="id">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Flex-wrap, Flex-flow, Gap - Demo Galeri</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            background: #f0f4f8;
            padding: 40px 20px;
        }
        .container {
            max-width: 1000px;
            margin: 0 auto;
            background: white;
            border-radius: 20px;
            padding: 30px;
            box-shadow: 0 4px 10px rgba(0,0,0,0.05);
        }
        h1 { text-align: center; margin-bottom: 10px; }
        .gallery {
            display: flex;
            flex-flow: row wrap;
            gap: 20px;
            margin: 30px 0;
        }
        .card {
            background: #f8fafc;
            border-radius: 12px;
            padding: 15px;
            width: calc(33.333% - 14px);
            text-align: center;
            transition: transform 0.2s;
        }
        .card:hover {
            transform: translateY(-5px);
            box-shadow: 0 8px 20px rgba(0,0,0,0.1);
        }
        .card img {
            width: 100%;
            border-radius: 8px;
            margin-bottom: 10px;
        }
        @media (max-width: 768px) {
            .card { width: calc(50% - 10px); }
        }
        @media (max-width: 480px) {
            .card { width: 100%; }
        }
        .info-box {
            background: #eef2ff;
            padding: 20px;
            border-radius: 12px;
            margin-top: 30px;
        }
        code {
            background: #e2e8f0;
            padding: 2px 6px;
            border-radius: 4px;
            font-family: monospace;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>Galeri Responsif dengan Flexbox</h1>
        <div class="gallery">
            <div class="card"><div style="background:#3b82f6; height:120px; border-radius:8px; margin-bottom:10px;"></div><h3>Gambar 1</h3></div>
            <div class="card"><div style="background:#22c55e; height:120px; border-radius:8px; margin-bottom:10px;"></div><h3>Gambar 2</h3></div>
            <div class="card"><div style="background:#ef4444; height:120px; border-radius:8px; margin-bottom:10px;"></div><h3>Gambar 3</h3></div>
            <div class="card"><div style="background:#f59e0b; height:120px; border-radius:8px; margin-bottom:10px;"></div><h3>Gambar 4</h3></div>
            <div class="card"><div style="background:#8b5cf6; height:120px; border-radius:8px; margin-bottom:10px;"></div><h3>Gambar 5</h3></div>
            <div class="card"><div style="background:#ec489a; height:120px; border-radius:8px; margin-bottom:10px;"></div><h3>Gambar 6</h3></div>
        </div>
        <div class="info-box">
            <h3>Ringkasan</h3>
            <ul>
                <li><code>flex-wrap: wrap</code> → item pindah baris jika tidak muat.</li>
                <li><code>flex-flow</code> → gabungan flex-direction dan flex-wrap.</li>
                <li><code>gap</code> → jarak antar item (baris dan kolom).</li>
            </ul>
        </div>
    </div>
</body>
</html>

Hasil visual galeri:

Galeri dengan flex-wrap: wrap dan gap: 15px. Responsif dengan media query.

Kesalahan Umum

  • Lupa menambahkan flex-wrap: wrap sehingga item overflow.
  • Mengira gap bisa menggantikan margin pada semua kasus (tidak untuk grid lama).
  • Tertukar urutan nilai pada flex-flow (direction dulu, baru wrap).

Latihan Singkat

  1. Buat flex container dengan 5 item, atur flex-wrap: wrap dan gap: 20px.
  2. Gunakan flex-flow: column wrap dengan tinggi container terbatas, lihat bagaimana item disusun.
  3. Buat galeri foto responsif dengan flex-wrap dan gap, serta media query untuk jumlah kolom.
  4. Coba perbedaan gap dengan margin pada item (gap lebih rapi karena tidak ada margin di tepi).

Intisari Hari Ini

  • flex-wrap → mengatur apakah item boleh pindah baris (wrap).
  • flex-flow → shorthand untuk flex-direction + flex-wrap.
  • gap → jarak antar item (baris dan kolom), lebih praktis dari margin.
  • Kombinasi flex-wrap + gap + media query sangat powerful untuk galeri responsif.
Tantangan: Buat halaman portofolio dengan galeri proyek menggunakan flex-wrap dan gap. Atur jumlah kolom: 3 di desktop, 2 di tablet, 1 di HP. Tambahkan efek hover scale pada kartu.

Artikel Sebelumnya: CSS Dasar #25 - align-items dan align-content
Artikel Selanjutnya: CSS Dasar #27 - Properti Flex Item: order, flex-grow, flex-shrink, flex-basis, align-self

Lebih baru Lebih lama

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