外边距重叠现象
CSS 外边距重叠的发生条件与解决方法
问题
什么是外边距重叠(Margin Collapse)?什么情况下会发生?如何避免?
解答
外边距重叠是指两个或多个垂直方向的外边距相遇时,会合并成一个外边距,取其中较大的值。
发生的三种情况
1. 相邻兄弟元素
<style>
.box1 {
margin-bottom: 30px;
background: lightblue;
}
.box2 {
margin-top: 20px;
background: lightgreen;
}
</style>
<div class="box1">Box 1</div>
<div class="box2">Box 2</div>
<!-- 两个盒子之间的间距是 30px,不是 50px -->
2. 父子元素
<style>
.parent {
background: lightblue;
/* 父元素没有 border、padding 或 BFC */
}
.child {
margin-top: 20px;
background: lightgreen;
}
</style>
<div class="parent">
<div class="child">Child</div>
</div>
<!-- 子元素的 margin-top 会"穿透"到父元素外部 -->
3. 空块元素
<style>
.empty {
margin-top: 20px;
margin-bottom: 30px;
/* 没有内容、padding、border、height */
}
</style>
<div class="empty"></div>
<!-- 自身的上下外边距会重叠,最终只有 30px -->
解决方法
方法一:创建 BFC
.parent {
overflow: hidden; /* 或 auto */
}
/* 或者 */
.parent {
display: flow-root; /* 推荐,专门用于创建 BFC */
}
方法二:添加边框或内边距
.parent {
padding-top: 1px; /* 或 border-top: 1px solid transparent */
}
方法三:使用 Flexbox 或 Grid
.parent {
display: flex;
flex-direction: column;
}
完整示例
<!DOCTYPE html>
<html>
<head>
<style>
/* 问题:父子外边距重叠 */
.problem .parent {
background: lightblue;
}
.problem .child {
margin-top: 30px;
background: lightgreen;
}
/* 解决:使用 t0dtt 创建 BFC */
.solution .parent {
background: lightblue;
display: flow-root;
}
.solution .child {
margin-top: 30px;
background: lightgreen;
}
</style>
</head>
<body>
<h3>问题:margin 穿透</h3>
<div class="problem">
<div class="parent">
<div class="child">Child</div>
</div>
</div>
<h3>解决:BFC 阻止穿透</h3>
<div class="solution">
<div class="parent">
<div class="child">Child</div>
</div>
</div>
</body>
</html>
关键点
- 只发生在垂直方向,水平方向不会重叠
- 重叠后取较大值(都为正),都为负取绝对值较大的,一正一负则相加
- 创建 BFC 可以阻止父子元素的外边距重叠
display: flow-root是创建 BFC 的最佳方式- Flexbox 和 Grid 布局中不存在外边距重叠
目录