Satuan px pada template grid menghasilkan kolom yang kaku: ketika wadah melebar atau menyempit, proporsi layout ikut rusak. Satuan fr — singkatan dari fraction — dibuat untuk masalah ini: 1fr berarti satu bagian dari ruang bebas kisi, sehingga kolom dapat berbagi ruang secara proporsional tanpa perhitungan persen manual. Pada Chapter ini kita membedah cara browser menghitung ukuran track fr, urutan prosesnya, dan satu perilaku halus yang sering mengejutkan: fr membagi ruang setelah kebutuhan minimal konten diperhitungkan.

Makna Satu Fraksi #

Deklarasi grid-template-columns: 1fr 2fr pada wadah 600px berarti ruang bebas dibagi menjadi tiga bagian sama; kolom pertama menerima satu bagian (200px) dan kolom kedua dua bagian (400px). Angka di depan fr adalah bobot, bukan ukuran mutlak — bila wadah membesar menjadi 900px, kolom yang sama menjadi 300px dan 600px dengan proporsi yang tetap 1:2.

Sifat proporsional inilah yang membuat fr menjadi satuan favorit untuk layout yang harus menyesuaikan lebar layar. Perbandingan yang sering dipakai:

TemplateKisi 600pxKisi 900px
1fr 1fr300px, 300px450px, 450px
1fr 2fr200px, 400px300px, 600px
1fr 1fr 1fr200px tiga kali300px tiga kali
200px 1fr200px, 400px200px, 700px

Baris terakhir pada tabel menunjukkan pola campuran yang berguna: satu kolom tetap untuk sidebar dan satu kolom fr untuk sisa ruang. Track fr tidak boleh bernilai nol atau negatif; 0fr setara dengan track yang hanya mengandung kebutuhan minimal kontennya.

Perlu dibedakan dari persen: grid-template-columns: 50% 50% mengukur 50% dari lebar wadah tanpa peduli konten dan tanpa memperhitungkan gap, sehingga penambahan gap membuat totalnya meluap melebihi wadah. Satuan fr bekerja pada ruang yang tersisa setelah gap dan kebutuhan minimal dilayani, sehingga kombinasi fr dengan gap, track tetap, maupun track auto tidak pernah meluap — itulah alasan fr dipilih untuk hampir semua template grid modern.

Urutan Perhitungan Browser #

Proses pengukuran track fr berjalan dalam urutan tertentu, dan memahaminya mencegah banyak kebingungan:

  1. Kurangi gap terlebih dahulu: total lebar semua column-gap dipotong dari lebar wadah sebelum pembagian fraksi. Wadah 600px dengan column-gap: 60px menyisakan 540px untuk didistribusikan.
  2. Sisakan kebutuhan minimal konten: setiap track fr memiliki ukuran minimal auto, yaitu min-content isinya. Browser menjamin bagian ini terlebih dahulu — inilah sebabnya sebuah kata panjang yang tidak dapat dipotong baris dapat memaksa kolom fr menjadi lebih lebar dari fraksi teoretisnya.
  3. Bagi sisa ruang secara proporsional: ruang yang tinggal dibagi sesuai bobot fr masing-masing track.

Karena langkah kedua, 1fr secara perilaku mendekati minmax(auto, 1fr). Bila Anda ingin kolom yang boleh menyusut di bawah kebutuhan kontennya, tulis eksplisit minmax(0, 1fr) — pola ini sering dipakai untuk tabel dan dashboard yang isinya tidak terprediksi.

Berikut HTML yang dipakai demo chapter ini:

html index.html
<!DOCTYPE html>
<html lang="id">
<head>
  <meta charset="utf-8">
  <title>Distribusi Fr</title>
  <style>
    .kisi { display: grid; width: 600px; grid-template-columns: 1fr 2fr; }
    .kisi-gap { display: grid; width: 600px; grid-template-columns: 1fr 2fr; gap: 60px; }
    .kisi > div, .kisi-gap > div { border: 1px solid rgb(59, 130, 246); background: rgb(219, 234, 254); }
  </style>
</head>
<body>
  <div class="kisi">
    <div>1fr</div>
    <div>2fr</div>
  </div>
  <div class="kisi-gap">
    <div>1fr</div>
    <div>2fr</div>
  </div>
</body>
</html>

Hasil di Browser:

text
Kisi pertama (1fr 2fr pada wadah 600px tanpa gap): item pertama
selebar 200px, item kedua 400px — proporsi 1:2 dari 600px.
Kisi kedua (gap 60px): 600px dikurangi 60px menyisakan 540px;
dibagi 1:2 menghasilkan 180px dan 360px. Computed width kedua item
sesuai angka tersebut.

Mari kita telaah dua deklarasi kuncinya:

  1. Baris 7 (grid-template-columns: 1fr 2fr): tanpa gap, seluruh 600px adalah ruang bebas; pembagian tiga bagian menghasilkan 200px dan 400px.
  2. Baris 10 (gap: 60px): gap dipotong lebih dulu, sehingga fraksi dihitung dari 540px — bukan 600px. Pembagian yang sama menghasilkan 180px dan 360px.

Demo chapter ini memuat penanda uji otomatis yang memverifikasi lebar 200px dan 400px pada kisi tanpa gap, serta 180px dan 360px pada kisi dengan gap 60px.