8.5 margin折叠的合理性
8.5.1 兄弟折叠的合理性示例
初始场景。段落p1与上下div的垂直margin值20px,效果如下。
初始代码
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>小步教程</title>
<style>
div{
background-color: #4aa6fc;
}
p{
margin: 20px 0 ;
background-color: #0aaa76;
}
</style>
</head>
<body>
<div class="div1">div1</div>
<p class="p1">p1 小步教程 xiaobuteach.com</p>
<!-- <p class="p2">p2 小步教程 xiaobuteach.com</p> -->
<div class="div2">div2</div>
</body>
</html>
新需求。p1后面加入p2,关键问题:期望p1与p2之间的margin间距是多少?
第1种设计:希望p1与p2之间的margin间距是40px。
第2种设计:希望p1与p2之间的margin间距仍然是20px。
第2种设计更符合当前场景,段落之间的间距仍然保持20px。所以,BFC模型设计自动的兄弟margin折叠,页面渲染时两者之间的margin折叠成20px。测试一致。
开发者工具识别兄弟margin折叠。分别选择p1与p2元素,查看盒子的页面显示,合并图如下。
如桔色区域所示,p1的margin-bottom与p2的margin-top区域完全重合。
8.5.2 父子折叠的合理性示例
初始页面场景。div2与上下div的垂直margin间距是20px,效果如下。
初始代码
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>小步教程</title>
<style>
div {
background-color: #4aa6fc;
}
.div2 {
margin: 20px 0;
}
</style>
</head>
<body>
<div class="div1">div1</div>
<div class="div2">
div2 小步教程 xiaobuteach.com
</div>
<div class="div3">div3</div>
</body>
</html>
新需求。div2内部替换成新的元素p1,p1本身也有设置margin-top,关键问题:期望div2与div1之间margin间距是多少?期望p1与div2上方margin间距是多少?
示例代码
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>小步教程</title>
<style>
div {
background-color: #4aa6fc;
}
.div2 {
margin: 20px 0;
}
p {
margin: 20px 0;
background-color: #0aaa76;
}
</style>
</head>
<body>
<div class="div1">div1</div>
<div class="div2">
<p class="p1">p1 小步教程 xiaobuteach.com</p>
</div>
<div class="div3">div3</div>
</body>
</html>
第1种设计:期望按照原始计算,分别是20px、20px。
第2种设计:期望尽量减少间距,对margin进行合并,p1显示在div1顶部。
第2种设计更符合当前场景,所以BFC模型设计了自动的父子margin折叠。测试一致。
开发者工具识别父子margin折叠。分别查看div2与p1,合并图如下。
如桔色区域所示,两者margin区域完全重合。
8.5.3 随处可见的margin折叠
浏览器为标签设置默认样式,即使没有手动设置任何样式,也经常发生margin重叠。
示例代码
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>小步教程</title>
</head>
<body>
<h3>小步教程 xiaobuteach.com</h3>
<p>小步教程 xiaobuteach.com</p>
</body>
</html>
body默认margin: 8px,h3默认margin绝对值18.72px 0,p默认margin绝对值16px 0。
分别选中body,h3,p元素,查看盒子的页面显示。
(1)body与h3的margin-top发生折叠,属于相邻父子折叠,而且body的margin-top被穿透(即子元素的margin-top超出父元素的margin-top)。
(2)h3的margin-bottom与p的margin-top发生折叠,属于相邻兄弟折叠。
(3)body与p的margin-bottom发生折叠,而且body的margin-bottom被穿透。
这些折叠具有合理性。也存在一些需求场景,不需要折叠,只想按原始方式计算与显示。