Khi hai margin theo chiều dọc chạm nhau, browser gộp thành một, lấy giá trị lớn hơn chứ không cộng.
css
.a { margin-bottom: 30px; }
.b { margin-top: 20px; }
/* khoảng cách thực tế giữa .a và .b = 30px, không phải 50px */Ba tình huống xảy ra:
html
<!-- 1. anh em liền kề -->
<p style="margin-bottom:30px">A</p>
<p style="margin-top:20px">B</p> <!-- cách 30px -->
<!-- 2. cha - con: margin con "thoát" ra ngoài cha -->
<div style="background:#eee"> <!-- không padding, không border -->
<h2 style="margin-top:40px">Tiêu đề</h2> <!-- 40px đẩy CẢ div xuống -->
</div>
<!-- 3. cha rỗng: margin-top và margin-bottom của chính nó gộp lại -->
<div style="margin:20px 0"></div> <!-- chiếm 20px, không phải 40px -->Không xảy ra với: margin ngang, flex item, grid item, element position: absolute/fixed, element tạo block formatting context (overflow: hidden, display: flow-root).
Cách chặn ở trường hợp cha–con:
css
.parent { display: flow-root; } /* sạch nhất, không tác dụng phụ */Chốt thực dụng: dùng gap của flex/grid thay cho margin dọc giữa các item: gap không bị gộp nên không phải nhớ quy tắc này.