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

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

由父子元素margin说开——外边距塌陷(margin-collapse)_第1张图片


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

代码如下:



	
		
		
		
	

	
      

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


由父子元素margin说开——外边距塌陷(margin-collapse)_第2张图片

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:



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

由父子元素margin说开——外边距塌陷(margin-collapse)_第3张图片
               
              https://jsfiddle.net/nekoloke/b8shusxq/
    
      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/

参考资料:http://stackoverflow.com/questions/19718634/how-to-disable-margin-collapsing
               http://www.ayqy.net/doc/css2-1/box.html#collapsing-margins
               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 
               https://www.sitepoint.com/web-foundations/collapsing-margins/


你可能感兴趣的:(css,布局)