Chapter-chapter sebelumnya mengatur bagaimana item flex tersusun: arah sumbu, pelipatan baris, perataan, dan jarak antar item. Masih ada dua situasi yang belum kita jawab. Pertama, ketika total ukuran item lebih kecil dari container, muncul ruang sisa yang menganggur di ujung. Kedua, ketika total ukuran item melebihi container, item harus menyusut agar tidak meluber. Dua property — flex-grow dan flex-shrink — mengatur kejadian tersebut, dan chapter ini membedah keduanya beserta hitungan konkret di baliknya.

Flex-Grow: Membagi Ruang Sisa #

flex-grow menentukan seberapa besar porsi seorang item ketika ada ruang bebas pada main axis. Nilai default-nya adalah 0: item tidak ikut membesar, sehingga ruang sisa terkumpul di ujung container seperti yang kita lihat pada chapter Justify-Content. Begitu sebuah item diberi flex-grow positif, ruang sisa dibagikan kepada para penerima secara proporsional terhadap rasio nilainya.

Pola paling umum adalah sidebar berukuran tetap di samping konten yang mengisi sisa ruang:

css
.layout-dua-kolom {
  display: flex;
  gap: 16px;
}

.sisi {
  width: 220px;
  flex-grow: 0; /* tidak ikut membesar */
}

.konten {
  flex-grow: 1; /* menyerap seluruh ruang sisa */
}

Mari kita hitung pembagiannya secara persis. Misalkan container selebar 900 piksel (kita abaikan gap demi kesederhanaan) berisi tiga item yang masing-masing berukuran dasar 100 piksel. Total ukuran dasar 300 piksel, sehingga ruang bebasnya 600 piksel. Berikan flex-grow: 1, 1, dan 2:

ItemUkuran dasarGrowPorsi ruang bebasUkuran akhir
Pertama100px1150px250px
Kedua100px1150px250px
Ketiga100px2300px400px

Total grow adalah 4, jadi satu “unit” porsi bernilai 600 ÷ 4 = 150 piksel. Perhatikan makna penting di balik angka ini: item dengan grow 2 mendapat dua kali porsi tambahan (300 piksel tambahan dibanding 150 piksel), tetapi ukuran akhirnya (400 piksel) bukan dua kali ukuran item lain (250 piksel). Flex-grow adalah pembagi ruang sisa, bukan pengali ukuran total — titik awal yang berbeda membuat perbandingan ukuran akhir ikut bergeser.

css
.baris-porsi {
  display: flex;
  gap: 12px;
}

.porsi-satu {
  flex-grow: 1;
}

.porsi-dua {
  flex-grow: 2;
}

Flex-Shrink: Menyusut Saat Ruang Kurang #

flex-shrink adalah cermin sekaligus kebalikan dari grow: property ini mengatur porsi penyusutan ketika total ukuran item melebihi container. Di sini ada kejutan bagi pemula — nilai default flex-shrink adalah 1, bukan 0. Artinya, item flex sudah menyusut secara default; itulah sebabnya deretan kotak berukuran tetap tidak meluber seperti kotak block biasa, melainkan saling memberi ruang.

Pembagiannya proporsional terhadap ukuran dasar item: bobot penyusutan dihitung dari nilai shrink dikali ukuran dasarnya. Untuk item berukuran dasar sama, porsi penyusutan sebanding langsung dengan nilai shrink-nya. Contoh: container 600 piksel menampung dua item berukuran dasar 400 piksel. Totalnya 800 piksel, kekurangannya 200 piksel, dan keduanya menyusut sama besar:

ItemUkuran dasarShrinkPenyusutanUkuran akhir
Pertama400px1100px300px
Kedua400px1100px300px

Nilai flex-shrink: 0 membuat item menolak menyusut sama sekali. Property ini berguna untuk elemen yang ukurannya tidak boleh berubah — tombol ikon, avatar, atau badge — sehingga beban penyusutan dialihkan ke item lain:

css
.tombol-ikon {
  flex-shrink: 0; /* ukuran tetap, tidak ikut menyusut */
}

.teks-utama {
  flex-shrink: 1; /* default: menyerap seluruh penyusutan */
}

Bila penyusutan melebihi yang bisa diserap .teks-utama, baris mulai meluber.

Demo berikut menampilkan ketiga pola pada lebar panggung yang sama — grow 0 vs grow 1, grow 1 vs grow 2, dan satu item shrink: 0 yang menolak menyusut:

Perkecil lebar demo dan amati panel biru baris bawah tidak pernah berubah ukuran, sementara panel merah terus menanggung penyusutan.

Kesalahan Umum #

KesalahanAkibatnyaPerbaikannya
Menganggap grow 2 membuat item dua kali lebih besarUkuran akhir tidak sesuai harapan karena titik awal tiap item berbedaPikirkan grow sebagai pembagi ruang sisa, bukan pengali ukuran total
Berharap item memenuhi container tanpa menulis apa punDefault flex-grow adalah 0, ruang sisa menganggur di ujungBeri flex-grow: 1 pada item yang harus mengisi ruang
Gambar atau tombol ikut gepeng saat layar sempitDefault flex-shrink adalah 1, semua item menyusutBeri flex-shrink: 0 pada elemen yang ukurannya tidak boleh berubah

Ringkasan #

flex-grow membagi ruang sisa secara proporsional terhadap rasio nilainya, sedangkan flex-shrink — yang aktif secara default — membagi beban penyusutan secara proporsional terhadap ukuran dasar item. Keduanya bekerja di atas satu pertanyaan yang belum kita jawab: dari mana ukuran dasar item itu berasal sebelum pembagian dimulai? Property yang menjawabnya adalah flex-basis, dan itulah topik chapter berikutnya.