margin 折叠(合并)的规则是什么?如何避免?
margin 折叠规则
相邻的垂直方向 margin 会合并(取较大值),水平方向不折叠。
三种折叠场景
1. 相邻兄弟元素
.box1 { margin-bottom: 20px; }
.box2 { margin-top: 30px; }
/* 间距 = max(20, 30) = 30px,不是 50px */2. 父元素与第一个/最后一个子元素
.parent { margin-top: 20px; }
.child { margin-top: 30px; }
/* parent 的上 margin = max(20, 30) = 30px */3. 空块元素自身的上下 margin
.empty {
margin-top: 20px;
margin-bottom: 30px;
/* 如果没有内容、padding、border,上下 margin 合并为 30px */
}折叠条件
- 都是块级元素(非浮动、非绝对定位)
- 在正常的文档流中
- 在垂直方向上相邻
如何避免
1. 父元素创建 BFC
.parent {
overflow: hidden;
/* 或 display: flow-root; */
}2. 添加 border 或 padding
.parent {
border-top: 1px solid transparent;
/* 或 */
padding-top: 1px;
}3. 使用 Flex/Grid 布局
.parent {
display: flex;
flex-direction: column;
}
/* Flex/Grid 中不存在 margin 折叠 */4. 使用 gap 代替 margin
.parent {
display: flex;
flex-direction: column;
gap: 20px;
}5. 浮动或绝对定位
.child {
float: left;
/* 或 position: absolute; */
/* 浮动/绝对定位元素不参与 margin 折叠 */
}负 margin 折叠
.box1 { margin-bottom: 20px; }
.box2 { margin-top: -10px; }
/* 间距 = 20 + (-10) = 10px(正负取和) */
.box1 { margin-bottom: -20px; }
.box2 { margin-top: -10px; }
/* 间距 = min(-20, -10) = -20px(都是负值取绝对值较大的) */