一、什么是外边距重叠?
外边距重叠也可以称之为外边距塌陷,见名可知其意,外边距重叠就是不同元素上下外边距重叠到一起,官方解释如下:
块的上外边距(margin-top)和下外边距(margin-bottom)有时合并(折叠)为单个边距,其大小为单个边距的最大值(或如果它们相等,则仅为其中一个),这种行为称为边距折叠。
从官方的定义中我们可以看出只有块级元素才会发生外边距重叠的情况,行内元素和行内块元素时不会发生外边距重叠问题的。
二、什么情况下会出现外边距重叠情况?
2.1、相邻兄弟元素之间
请看如下示例代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>外边距重叠问题</title>
<style>
.baseStyle{
width: 100px;
height: 100px;
text-align: center;
line-height: 100px;
color: white;
}
#upDiv{
background-color: #023d69;
margin-bottom: 50px;
}
#downDiv{
background-color: #f97304;
margin-top: 50px;
}
</style>
</head>
<body>
<div id="wrapper" class="wrapper">
<div id="upDiv" class="baseStyle">
上块级元素
</div>
<div id="downDiv" class="baseStyle">
下块级元素
</div>
</div>
</body>
</html>
#upDiv和#downDiv为紧邻的兄弟元素,#upDiv和#downDiv在浏览器渲染时出现外边距重叠的情况,且保留了#downDiv元素这个较大的外边距。请先看如下的gif动图演示:
如果需要解决此问题,则需要在后一个元素中开启float浮动定位,具体如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>外边距重叠问题</title>
<style>
.baseStyle{
width: 100px;
height: 100px;
text-align: center;
line-height: 100px;
color: white;
}
#upDiv{
background-color: #023d69;
margin-bottom: 50px;
}
#downDiv{
background-color: #f97304;
margin-top: 50px;
float: left;
}
</style>
</head>
<body>
<div id="wrapper" class="wrapper">
<div id="upDiv" class="baseStyle">
上块级元素
</div>
<div id="downDiv" class="baseStyle">
下块级元素
</div>
</div>
</body>
</html>
此外,因为子元素开启了float定位,所以父元素#wrapper又出现了高度塌陷的问题,需要使用如下的方式解决高度塌陷问题:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>外边距重叠问题</title>
<style>
.wrapper::after{
clear: left;
content: '';
display: block;
}
.baseStyle{
width: 100px;
height: 100px;
text-align: center;
line-height: 100px;
color: white;
}
#upDiv{
background-color: #023d69;
margin-bottom: 50px;
}
#downDiv{
background-color: #f97304;
margin-top: 50px;
float: left;
}
</style>
</head>
<body>
<div id="wrapper" class="wrapper">
<div id="upDiv" class="baseStyle">
上块级元素
</div>
<div id="downDiv" class="baseStyle">
下块级元素
</div>
</div>
</body>
</html>
2.2、相邻父子(第一个子元素)元素之间
请看如下代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>外边距重叠问题</title>
<style>
#box{
width: 200px;
height:200px;
background:#023d69;
}
#subDiv{
width: 100px;
height:100px;
background:#f97304;
margin-top:50px ;
}
</style>
</head>
<body>
<div id="box">
<div id="subDiv">
这里是subDiv
</div>
</div>
</body>
</html>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-92T7av3P-1681287919792)(637be8a7c408a1ce8bb47392a8b9ba34.png)]
从代码可以看出我们目的是想让子元素距离父元素的顶部50px,可惜结果总是在意料之外,父级会和子级移动,距离顶部50px。有如下6种方案解决这个问题。
方式一:给父元素添加overflow:hidden
<style>
#box{
width: 200px;
height:200px;
background:#023d69;
overflow: hidden;
}
#subDiv{
width: 100px;
height:100px;
background:#f97304;
margin-top:50px ;
}
</style>
这种方法解决了我们外边距重叠问题,但是这个方法只适用于 “子元素的高度加上外边距高度小于父元素高度(childHeight +margin-top<parentHeight)” ,不然子元素部分内容就会被隐藏掉。
方式二:给父元素加边框 border
<style>
#box{
width: 200px;
height:200px;
background:#023d69;
border: 1px solid red;
}
#subDiv{
width: 100px;
height:100px;
background:#f97304;
margin-top:50px ;
}
</style>
父子元素是外边框重叠到一起去了 ,那么我们给父元素加个边框,他们的外边距就有了边框的间距,但是这样也就多出来没有必要的边框。
方式三:给父级或者子级设置display:inline-block;
<style>
#box{
width: 200px;
height:200px;
background:#023d69;
display: inline-block;
}
#subDiv{
width: 100px;
height:100px;
background:#f97304;
margin-top:50px ;
}
</style>
既然只有块元素会产生外边距重叠,那么我们就让它不是块元素,把它设置为行内块元素。
方式四:给父级或者子级设置float
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>外边距重叠问题</title>
<style>
#main::after{
clear: left;
content: '';
display: block;
}
#box{
width: 200px;
height:200px;
background:#023d69;
float: left;
}
#subDiv{
width: 100px;
height:100px;
background:#f97304;
margin-top:50px ;
/* float: left; */
}
</style>
</head>
<body id="main">
<div id="box">
<div id="subDiv">
这里是subDiv
</div>
</div>
</body>
</html>
注意,这种方式也会导致父元素高度塌陷问题,需要清除浮动。
方式五:给父级或者子级设置position: absolute
<style>
#box{
width: 200px;
height:200px;
background:#023d69;
/* position: absolute; */
}
#subDiv{
width: 100px;
height:100px;
background:#f97304;
margin-top:50px ;
position: absolute;
}
</style>
这种方式本质上是将元素脱离文档流,你是你,我是我,相互不影响。
方式六:给父元素添加padding
<style>
#box{
width: 200px;
height:200px;
background:#023d69;
padding: 0.1px;
}
#subDiv{
width: 100px;
height:100px;
background:#f97304;
margin-top:50px ;
}
</style>
这种方式和给父元素添加border区别不大,会有多余的样式产生;如果非得这么做,那就尽量把padding的值设置的小一点儿。
三、外边距重叠如何计算?
- 两个正数取最大的数。
- 两个负数取绝对值最大的数。
- 一正一负取两者之和。