Grid adalah model layout CSS yang menyusun elemen dalam baris dan kolom sekaligus, sehingga satu kontainer membentuk kisi dua dimensi. Topik ini membahas pembentukan konteks formatting grid melalui display: grid, konsep track dan sel sebagai kerangka kisi, satuan fr untuk pembagian ruang, serta properti gap untuk penjarakan antar track. Perbedaan arah kerja grid dengan flexbox juga diuraikan, dan topik ditutup dengan pola nyata berupa halaman berisi kisi kartu catatan.
Konteks formatting grid#
Deklarasi display: grid mengubah sebuah elemen menjadi kontainer grid, yaitu elemen yang membentuk konteks formatting grid bagi anak-anaknya. Anak langsung dari kontainer tersebut menjadi item grid dan disusun mengikuti kisi yang didefinisikan. Elemen yang berada lebih dalam, misalnya paragraf di dalam sebuah kartu, tidak ikut disusun oleh kontainer tersebut dan tetap mengikuti aturan layout di dalam itemnya sendiri.
Kerangka kisi tersusun atas track, yakni setiap baris dan kolom pembentuk kisi. Perpotongan satu kolom dengan satu baris membentuk sel, dan satu item menempati satu sel atau lebih. Properti grid-template-columns menentukan jumlah dan ukuran track kolom, sedangkan track baris yang tidak dideklarasikan terbentuk secara implisit mengikuti kebutuhan item.
.kisi {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
gap: 16px;
}Pada contoh di atas, .kisi menjadi kontainer grid dengan tiga track kolom yang sama lebar dan jarak 16 piksel di antara tracknya. Item-item di dalamnya mengisi kisi dari kiri ke kanan, lalu pindah ke baris berikutnya setelah track kolom habis. Pola pengisian otomatis ini berlaku selama item tidak diberi penempatan eksplisit, sehingga urutan HTML menentukan urutan kartu pada kisi.
Satuan fr untuk pembagian ruang#
Satuan fr, kependekan dari fraction, menyatakan satu bagian dari ruang tersisa pada kontainer. Ruang tersisa dihitung setelah ukuran track tetap dan gap diperhitungkan, sehingga fr menggambarkan proporsi dan bukan ukuran pasti. Templat 1fr 1fr 1fr membagi ruang tersebut menjadi tiga bagian sama besar.
Pada kontainer selebar 900 piksel dengan gap 16 piksel, ruang yang tersedia untuk kolom adalah piksel. Lebar setiap kolom pada templat 1fr 1fr 1fr dihitung sebagai berikut.
Proporsi berbeda diperoleh dengan mengubah nilai fr pada templatnya. Templat 2fr 1fr pada kontainer yang sama menghasilkan kolom selebar piksel dan piksel. Nilai fr dihitung ulang setiap kali lebar kontainer berubah, sehingga pembagian tetap proporsional pada semua ukuran layar tanpa perhitungan ulang yang ditulis manual.
Satuan fr juga dapat dicampur dengan satuan tetap. Templat 240px 1fr membentuk kolom pertama selebar tetap 240 piksel, sedangkan kolom kedua menyerap seluruh sisa ruang. Pola ini lazim digunakan untuk pasangan bilah samping dan konten utama karena lebar bilahnya stabil, sedangkan kontennya menyesuaikan diri.
Jarak antar track dengan gap#
Properti gap memberi jarak tetap di antara track tanpa menyentuh tepi kontainer. Satu nilai berlaku untuk kedua arah, sedangkan dua nilai berarti jarak baris terlebih dahulu lalu jarak kolom. Properti row-gap dan column-gap tersedia bila salah satu arah perlu diatur sendiri, dan nilainya boleh berupa satuan tetap maupun satuan relatif seperti persen atau rem.
.kisi {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
gap: 24px 16px;
}Deklarasi gap: 24px 16px pada contoh di atas memberi jarak antar baris 24 piksel dan antar kolom 16 piksel. Ruang gap hanya muncul di antara track, sehingga baris pertama tetap menempel tepi atas kontainer dan kolom pertama tetap menempel tepi kirinya. Perilaku ini berbeda dengan margin yang juga menambah jarak pada tepi luar elemennya.
Berbeda dengan elemen block pada alur normal, item grid tidak mengalami penggabungan margin. Apabila satu kartu memiliki margin bawah dan kartu di bawahnya memiliki margin atas, kedua margin itu tetap berlaku, sehingga jarak antar kartunya menjadi jumlah keduanya. Karena itu gap lebih terprediksi daripada margin untuk penjarakan antar kartu, dan margin sebaiknya disimpan untuk jarak di dalam masing-masing kartu.
Grid dan flex pada dua dimensi#
Flexbox bekerja pada satu dimensi, yaitu menyusun item sepanjang satu baris atau satu kolom. Apabila item dibungkus ke baris baru, baris tersebut tetap bagian dari satu alur yang sama dan tingginya mengikuti konten. Grid bekerja pada dua dimensi karena kolom dan baris dideklarasikan bersamaan, sehingga posisi item dapat ditentukan sampai ke perpotongan keduanya. Tabel berikut merangkum perbedaan keduanya.
| Aspek | Flexbox | Grid |
|---|---|---|
| Dimensi kerja | satu sumbu, baris atau kolom | dua sumbu, baris dan kolom |
| Deklarasi track | tidak ada, ukuran mengikuti konten | grid-template-columns dan grid-template-rows |
| Penempatan item | mengikuti urutan alur | berdasarkan garis, rentang, atau area |
| Pemakaian yang cocok | navbar, kelompok tombol | kisi kartu, kerangka halaman |
Grid dan flexbox bukan dua model yang harus dipilih salah satunya. Kerangka halaman dan kisi kartu cocok menggunakan grid karena strukturnya dua dimensi, sedangkan komponen sepanjang satu baris seperti navbar tetap nyaman menggunakan flexbox. Kedua model juga dapat dipadukan pada satu halaman, misalnya grid untuk kerangka halaman dan flex di dalam setiap kartu untuk menata judul beserta tombolnya.
Pola nyata: kisi kartu catatan#
Halaman catatan belajar menjadi contoh penerapan kontainer grid. Enam kartu disusun pada tiga kolom 1fr dengan gap 16 piksel, dan setiap kartu diberi padding, border, serta latar putih di atas latar halaman yang abu-abu. Seluruh perbedaan tampilan antar kartu berasal dari isi teksnya, sedangkan ukuran dan jaraknya diatur seragam oleh kisi.
Perhatikan dua hal pada demo berikut. Pertama, ketiga kolom selalu sama lebar karena fr membagi ruang secara proporsional, dan lebar itu dihitung ulang saat panel pratinjau diubah ukurannya. Kedua, jarak antar kartu konsisten 16 piksel pada kedua arah karena gap yang ditetapkan pada kontainernya. Berkas index.css demo memuat deklarasi kunci pada selector .kisi.
Kode sumber demo
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8">
<title>Kisi kartu catatan tiga kolom</title>
<link rel="stylesheet" href="index.css">
</head>
<body>
<h1>Catatan belajar</h1>
<div class="kisi">
<article class="kartu">
<h2>Cascade</h2>
<p>Urutan sumber menentukan pemenang ketika dua deklarasi saling bertentangan.</p>
</article>
<article class="kartu">
<h2>Specificity</h2>
<p>Selector dengan bobot lebih tinggi mengalahkan bobot yang lebih rendah.</p>
</article>
<article class="kartu">
<h2>Inheritance</h2>
<p>Properti turunan seperti color diwarisi oleh elemen anak secara otomatis.</p>
</article>
<article class="kartu">
<h2>Box model</h2>
<p>Ukuran kotak content-box mencakup padding dan border di luar width.</p>
</article>
<article class="kartu">
<h2>Satuan relatif</h2>
<p>Nilai rem mengikuti ukuran huruf akar sehingga skala halaman konsisten.</p>
</article>
<article class="kartu">
<h2>Shorthand</h2>
<p>Urutan nilai shorthand padding mengikuti arah jarum jam dari sisi atas.</p>
</article>
</div>
<style>
/* Demo kontainer grid: kisi kartu catatan tiga kolom fr */
body {
margin: 0;
padding: 20px;
font-family: sans-serif;
background: #f1f5f9;
}
h1 {
font-size: 18px;
margin: 0 0 16px;
}
.kisi {
display: grid;
grid-template-columns: 1fr 1fr 1fr; /* tiga kolom sama lebar */
gap: 16px; /* jarak antar baris dan kolom */
}
.kartu {
margin: 0;
padding: 14px;
background: #ffffff;
border: 1px solid #cbd5e1;
border-radius: 6px;
}
.kartu h2 {
margin: 0 0 6px;
font-size: 14px;
}
.kartu p {
margin: 0;
font-size: 13px;
color: #475569;
}
</style>
<style>
/* Demo kontainer grid: kisi kartu catatan tiga kolom fr */
body {
margin: 0;
padding: 20px;
font-family: sans-serif;
background: #f1f5f9;
}
h1 {
font-size: 18px;
margin: 0 0 16px;
}
.kisi {
display: grid;
grid-template-columns: 1fr 1fr 1fr; /* tiga kolom sama lebar */
gap: 16px; /* jarak antar baris dan kolom */
}
.kartu {
margin: 0;
padding: 14px;
background: #ffffff;
border: 1px solid #cbd5e1;
border-radius: 6px;
}
.kartu h2 {
margin: 0 0 6px;
font-size: 14px;
}
.kartu p {
margin: 0;
font-size: 13px;
color: #475569;
}
</style></body>
</html>Berkas HTML demo hanya berisi enam elemen article di dalam satu div, sedangkan seluruh pengaturan kolom dan jaraknya berada pada deklarasi .kisi. Perpindahan dari tiga kolom ke dua kolom cukup dilakukan dengan mengubah satu baris templat, tanpa menyentuh markah sama sekali. Pemisahan peran seperti inilah yang membuat kisi kartu mudah dipelihara.
Kesalahan umum#
Kesalahan pertama adalah menganggap 1fr selalu menghasilkan kolom sama lebar. Nilai 1fr sesungguhnya berarti minmax(auto, 1fr), sehingga ukuran minimum tracknya adalah lebar konten terkecil yang tidak dapat dipatah, misalnya satu kata panjang atau tautan URL yang utuh. Satu kartu berisi konten semacam itu memaksa kolomnya melebar, dan kolom lain menyusut mengikuti sisa ruang. Kondisi ini mudah diuji dengan menambahkan satu kata panjang tanpa spasi pada salah satu kartu, lalu membandingkan lebar ketiga kolomnya. Cara perbaikannya adalah menetapkan batas minimum nol pada setiap kolom.
.kisi {
grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1fr);
}Kesalahan kedua adalah menggunakan margin pada kartu untuk menjarakkan kisi. Margin menambah jarak pada tepi luar baris pertama dan kolom pertama, sehingga kisi tampak bergeser dari batas kontainernya. Gunakan gap pada kontainer untuk jarak antar kartu, lalu sisakan margin untuk jarak di dalam kartu, misalnya antara judul dan ringkasan. Apabila jarak antar kartu perlu berbeda antara baris dan kolom, gunakan bentuk dua nilai dari gap itu sendiri, bukan margin tambahan.
Ringkasan#
display: gridmenjadikan elemen kontainer grid dengan konteks formatting dua dimensi, dan anak langsungnya menjadi item grid.- Track adalah baris atau kolom pembentuk kisi, sedangkan sel adalah perpotongan keduanya.
- Satuan
frmembagi sisa ruang setelah ukuran tetap dan gap diperhitungkan, dengan proporsi mengikuti pembilangnya. gapmemberi jarak antar track tanpa memengaruhi tepi kontainer, dan item grid tidak mengalami penggabungan margin.- Grid cocok untuk kisi kartu dan kerangka halaman karena bekerja dua dimensi, sedangkan flexbox satu dimensi.
Referensi#
- Basic concepts of grid layout — MDN Web Docs — Konsep dasar grid meliputi kontainer, item, track, dan sel beserta penjelasan satuan fr.
- CSS Grid Layout Module Level 2 — CSS Working Group — Spesifikasi resmi grid yang mendefinisikan konteks formatting grid, satuan fr, dan properti gap.
- gap — MDN Web Docs — Dokumentasi properti gap beserta turunannya, yaitu row-gap dan column-gap.
- Grid — web.dev — Materi kursus Learn CSS tentang konsep inti grid dan pembagian ruang dengan satuan fr.