由父子元素margin说开——外边距塌陷(margin-collapse)

布局时往往要遇到div嵌套显示效果,如下:



假设蓝色的为div1,黄色的为div2,为了实现上图所示布局,我的想法是为demo1设置margin:0px auto; demo2位置margin:30px,auto;

代码如下:

<span style="font-size:14px;"><!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title></title>
		<style>
		body{
			background-color: darkgray;
		}
		*{
			margin:0px;
			padding: 0px;
		}
		.div1{
			width:800px;
			height: 200px;
			background-color: cornflowerblue;
			margin:0px auto;
		}
		.div2{
			width:80%;
			height: 10%;
			background-color: wheat;
			margin: 30px auto;
		}
		</style>
	</head>

	<body>
      <div class="div1">
      	 <div class="div2">     	 	
      	 </div>
      </div>
	</body>

</html></span>

然而在浏览器里的结果显示如下:


div1随着div2往下走了30px,而div2相对div1的位置却没有变,这是为什么呢?

看上去父子元素的margin-top合并了。流内块级元素的top与bottom外边距有时会合并(塌陷)为单个外边距(合并后最大的外边距),这样的现象称之为外边距塌陷(margin collapsing

塌陷只存在与相邻的垂直外边距,即只涉及到margin-top/bottom,水平(margin-left/rignt无)
以下三种情况会出现外边距塌陷:

     1.      毗邻兄弟元素之间:
  • 若两者都为正外边距以最大的外边距为准;
  • 若存在负边距, 合并后的外边距为最大正外边距减去绝对值最大的负边距;
  • 若无正外边距,则用0减去绝对值最大负边距。

     2.      父元素与第一个/最后一个子元素之间
如果块元素的 margin-top 与它的第一个子元素的margin-top 之间没有 border、padding、inline content、 clearance 来分隔,或者块元素的 margin-bottom 与它的最后一个子元素的margin-bottom 之间没有 border、padding、inline content、height、min-height、 max-height 分隔,那么外边距会塌陷。子元素多余的外边距会被父元素的外边距截断。

  • margin-top:



               
          父元素无 border、padding、inline content(例子中::before伪元素为绝对定位脱离正常流,所以不算inline content) 、 clearance,父子元素的margin-top塌陷,此时子元素margin-top:30px,使得父子元素同时移动。
  • margin-bottom:
               
               若给父元素添加height,且height不能为auto,只能为绝对数值或者百分比(margin-top不受height影响),则塌陷效果被消除。
              
       若给父元素添加min-height,则父元素底部外边距依然受子元素影响,需通过border/padding/inline content/overflow消除。

               
    
      3.     自身合并        

一个盒的top和bottom margin,该盒没有建立一个新的块格式化上下文并且'min-height'的计算值为0,'height'的计算值为0或者'auto',并且没有流内子级

官方文档Note:

- 一个浮动的盒与任何其它盒之间的margin不会合并(甚至一个浮动盒与它的流内子级之间也不会)
- 建立了新的块格式化上下文的元素(例如,浮动盒与'overflow'不为'visible'的元素)的margin不会与它们的流内子级合并
- 绝对定位的盒的margin不会合并(甚至与它们的流内子级也不会)
- 内联盒的margin不会合并(甚至与它们的流内子级也不会)
- 一个流内块级元素的bottom margin总会与它的下一个流内块级兄弟的top margin合并,除非兄弟有空隙
- 一个流内块级元素的top margin会与它的第一个流内块级子级的top margin合并,如果该元素没有top border,没有top padding并且该子级没有空隙
- 一个'height'为'auto'并且'min-height'为0的流内块级盒的bottom margin会与它的最后一个流内块级子级的bottom margin合并,如果该盒没有bottom padding并且没有bottom border并且子级的bottom margin不与有空隙的top margin合并
- 盒自身的margin也会合并,如果'min-height'属性为0,并且既没有top或者bottom border也没有top或者bottom padding,并且其'height'为0或者'auto',并且不含行盒,并且其所有流内子级的margin(如果有的话)都合并了

       解决父子元素的外边距塌陷方法:
  • border:1px solid transparent;
  • padding;
  • float:left/right
  • position:absolute
  • display:inline-block
  • overflow:hidden/auto

附一个padding解决塌陷问题的例子:https://jsfiddle.net/nekoloke/975xstz9/

               https://www.w3.org/TR/CSS22/box.html#collapsing-margins(官方原文)
https://developer.mozilla.org/zh-CN/docs/Web/CSS/CSS_Box_Model/Mastering_margin_collapsing 


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值