Di chapter Margin kita menulis margin untuk mengatur jarak, tetapi ada satu perilaku vertikal yang belum dibedah: dua margin yang bertemu tidak saling berjumlah, melainkan bergabung menjadi satu. Beri elemen pertama margin-bottom: 24px dan elemen kedua margin-top: 16px, lalu jarak yang muncul bukan 40px — melainkan 24px. Perilaku ini disebut margin collapse dan berlaku khusus pada margin vertikal elemen block di alur normal. Tanpa memahaminya, jarak pada halaman terasa berubah sendiri; pada chapter ini kita mengenali tiga kasus utamanya, kondisi yang mencegahnya, serta cara mengendalikannya.
Margin Vertikal yang Bergabung #
Aturan dasarnya satu kalimat: ketika margin-bottom sebuah elemen block bertemu dengan margin-top elemen block tetangganya di bawahnya, kedua nilai mencollapse menjadi satu ruang sebesar nilai yang lebih besar:
.kartu-ringkas {
margin-bottom: 24px;
}
.kartu-ringkas + .kartu-ringkas {
margin-top: 16px; /* tidak dijumlahkan dengan 24px di atasnya */
}Demo memakai reset="false" agar default browser yang terasa. Bagian atas menunjukkan dua kotak yang marginnya mencollapse; bagian bawah membandingkan panel yang margin judulnya lolos dengan panel yang dipisah satu piksel padding — kasus yang kita bedah pada bagian berikutnya:
Jarak yang muncul antara kedua kotak itu 24px — nilai yang lebih besar — bukan hasil penjumlahan 40px.
margin-bottom elemen atas : 24px ─┐
margin-top elemen bawah : 16px ─┴─ collapse → satu ruang 24pxDua catatan penting: collapse hanya terjadi secara vertikal — margin kiri dan kanan tidak pernah bergabung — dan hanya pada elemen block yang bertetangga di alur normal. Bila salah satu margin bernilai negatif, nilai positif terbesar dijumlahkan dengan nilai negatif yang paling jauh di bawah nol: margin +24px dan -8px menghasilkan ruang 16px.
Margin Anak yang Lolos dari Induk #
Kasus kedua lebih sering mengejutkan. Bila tidak ada border, padding, atau konten inline yang memisahkan tepi atas induk dengan margin-top anak pertamanya, margin tersebut mencollapse dengan margin induk dan lolos ke luar — induklah yang terdorong:
<section class="panel">
<h2>Sepuluh resep kopi</h2>
</section>.panel {
background-color: #f4fbf7;
}
.panel h2 {
margin-top: 32px; /* mencollapse dengan induk, mendorong panel ke bawah */
}Niatnya memberi jarak di dalam panel, hasilnya justru jarak di luar panel.
Kasus ketiga: blok kosong. Elemen block tanpa konten, padding, border, dan tinggi mencollapse pada dirinya sendiri — margin atas dan bawahnya menyatu menjadi satu. Dua paragraf yang dipisah div kosong bermargin 24px hanya terlihat terpisah 24px, bukan 48px. Perbaikan termudahnya menghapus elemen kosong tersebut.
Kondisi yang Mencegah Collapse #
Collapse adalah perilaku default elemen block di alur normal, dan berhenti begitu elemen keluar dari aturan itu:
- Flex dan Grid container: margin antar item flex/grid tidak pernah mencollapse — salah satu alasan
gapmenjadi cara utama mengatur jarak di keduanya. - Elemen pembentuk BFC: elemen dengan
overflow: hidden,auto, atauscroll, serta elemen ber-display: flow-root, menahan margin anaknya agar tidak lolos ke luarnya. - Float dan position: absolute: elemen yang di-float atau diposisikan tidak lagi bertetangga di alur normal sehingga tidak ikut mencollapse.
Solusi: display: flow-root #
Ketika margin anak harus tetap berada di dalam induk, cara paling bersih adalah menjadikan induk pembentuk block formatting context (BFC):
.panel {
display: flow-root; /* margin anak ditahan di dalam induk */
}Property ini didukung seluruh browser modern dan tanpa efek samping: tidak memotong konten, tidak mengubah model layout. Alternatif lama yang masih sering dijumpai adalah overflow: hidden — memang menahan margin, tetapi ikut memotong konten yang menonjol seperti dropdown atau tooltip. Opsi lain yang ringan: menambahkan padding-top: 1px atau border-top pada induk sudah cukup memutus collapse, karena keduanya memisahkan tepi induk dari margin anak.
Kesalahan Umum #
| Gejala | Penyebab | Perbaikan |
|---|---|---|
| Jarak vertikal lebih kecil dari jumlah margin yang ditulis | Dua margin bertetangga mencollapse ke nilai terbesar | Terima perilakunya, atau atur jarak hanya dari satu sisi (misalnya hanya margin-bottom) |
| Latar panel tidak menutupi ruang di atas judulnya | Margin-top anak pertama lolos dari induk | Beri induk padding atau border, atau pakai display: flow-root |
| Jarak tak terduga di sekitar div kosong | Blok kosong mencollapse margin atas-bawahnya sendiri | Hapus elemen kosong, atau beri padding dan height |
| Margin antar kartu tidak berpengaruh di dalam flex | Item flex/grid tidak pernah mencollapse margin | Gunakan gap pada container |
Ringkasan #
Margin collapse menggabungkan margin vertikal elemen yang bertetangga menjadi satu ruang sebesar nilai terbesar — terjadi antar sibling, antara induk dengan anak pertama dan terakhirnya, serta pada blok kosong. Perilaku ini tidak terjadi di flex dan grid, pada elemen pembentuk BFC, maupun pada float dan elemen terposisi; bila margin anak harus tertahan di dalam induk, display: flow-root adalah solusi paling bersih. Setelah jarak vertikal terkendali, kita kembali ke ukuran kotak: chapter berikutnya memperdalam box-sizing dengan pola reset dan interaksinya bersama min-/max-width.