Kita sering mengira jarak antara dua elemen adalah jumlah margin keduanya. Kenyataannya, pada elemen block dalam normal flow, margin bawah elemen pertama dan margin atas elemen kedua bergabung menjadi satu jarak sebesar nilai terbesar di antara keduanya — perilaku yang disebut margin collapse . Perilaku ini terjadi tanpa peringatan dan menjadi sumber kebingungan klasik: jarak yang tampil lebih kecil dari perhitungan, atau margin anak yang tampak “bocor” ke luar induknya. Chapter ini membedah tiga kasus collapse, kondisi yang menghentikannya, dan cara membaca jarak dengan benar.
Tiga Kasus Margin Collapse #
| Kasus | Contoh | Jarak efektif |
|---|---|---|
| Elemen bertetangga | margin-bottom 24px bertemu margin-top 16px | max(24, 16) = 24px |
| Induk dengan anak pertama/terakhir | anak margin-top 40px, induk tanpa padding dan border | 40px tampil di luar induk |
| Blok kosong | blok tanpa isi, margin-top 20px dan margin-bottom 30px | satu jarak 30px |
Kasus pertama adalah yang paling sering ditemui: dua kotak block yang bersentuhan vertikal menggabungkan margin pertemuannya. Karena yang dipakai hanya nilai terbesar, jarak yang tampil lebih kecil daripada jumlah kedua margin.
Kasus kedua melibatkan induk dan anak. Margin atas anak pertama bergabung dengan margin atas induknya bila di antara keduanya tidak ada padding, border, maupun konten inline; aturan yang sama berlaku untuk margin bawah anak terakhir. Hasilnya margin berpindah posisi: induk ikut terdorong, dan tidak ada jarak di dalam kotak induk.
Kasus ketiga menyangkut blok yang tidak memiliki isi, border, padding, maupun tinggi. Blok kosong semacam itu memiliki tinggi nol, sehingga margin atas dan bawahnya bertemu dan bergabung menjadi satu jarak tunggal.
Kondisi yang Menghentikan Collapse #
Collapse hanya terjadi pada elemen block dalam normal flow, dan berhenti ketika ada pemisah. Kondisi-kondisi berikut menghentikannya:
- Padding atau border pada induk di sisi yang bertemu margin anak — margin anak tidak lagi merambat keluar.
- Block formatting context (BFC) baru pada induk, misalnya lewat
display: flow-rootatauoverflowselainvisible. - Container flex atau grid — margin antar itemnya dihitung penuh dan tidak saling bergabung.
- Elemen yang mengambang atau diposisikan (
float,position: absolute) — marginnya tidak bergabung dengan tetangganya.
.induk-bfc {
display: flow-root; /* margin anak tidak merambat keluar */
}
.induk-flex {
display: flex;
flex-direction: column;
gap: 8px; /* jarak antar item diatur gap, bukan collapse */
}Membaca Jarak yang Benar #
Nilai computed margin yang terbaca pada masing-masing elemen tetap merupakan nilai deklarasinya — elemen dengan margin-bottom: 24px tetap melaporkan 24px meskipun jarak nyatanya 24px karena collapse dengan margin 16px milik tetangganya. Yang bergabung adalah efek posisi, bukan nilai properti. Karena itu harness uji pada Course ini memeriksa nilai margin tiap elemen, bukan jarak antarelemen yang sedang bergabung.
Hasil di Browser:
Kotak-atas dan kotak-bawah bersentuhan dengan jarak 24px, bukan 40px:
margin-bottom 24px dan margin-top 16px bergabung menjadi satu nilai
terbesar. Anak dengan margin-top 40px di dalam induk tanpa padding dan
border menampilkan jaraknya di luar induk; setelah induk diberi
padding-top 1px, jarak 40px berpindah ke dalam. Blok kosong setinggi
0px menggabungkan margin-top 20px dan margin-bottom 30px menjadi satu
jarak 30px. Pada induk display: flow-root dan pada container flex,
margin 24px dan 16px dihitung penuh tanpa bergabung.Demo chapter ini memvisualkan kelima situasi pada tabel dan contoh di atas: dua kasus pertama pada dua panel berbeda, blok kosong di panel ketiga, serta dua kondisi penghenti collapse — flow-root dan container flex — di panel keempat. Panel-panelnya diberi padding agar margin tidak merambat keluar dan memengaruhi layout halaman demo itu sendiri.