margin重叠

CSS中,两个或者多个盒(可能但不一定是兄弟)的相邻的margin会被结合成一个margin。Margin按这种方式结合叫重叠(collapse)
,产生的结合的margin叫做重叠margin。

margin重叠的计算规则

两个margin是相邻的,当且仅当:

  • 都属于流内块级盒,处于同一个块格式化上下文。
  • 没有行盒(line box),没有空隙,没有padding并且没有border把它们隔开(注意,因此某些0高度行盒)
  • 都属于竖直相邻盒边(vertically-adjacent box edges),即来自下列某一对:
    1.一个盒的top margin和它的第一个流内子级的top margin
    2.一个盒的bottom margin和它的下一个流内后面的兄弟(its next in-flow following sibling)的top margin
    3.最后一个流内子级的bottom margin和它的父级的bottom margin,如果父级的高度的计算值为’auto’
    4.一个盒的top和bottom margin,该盒没有建立一个新的块格式化上下文并且min-height的计算值为0,height的计算值为0或者’auto’,并且没有流内子级

如果一个margin的任何部分margin与另一个margin相邻的话,就认为它与那个margin相邻,是合并(collapsed)margin。

具体分析各个条件

1、都属于流内块级盒,处于同一个块格式化上下文。

什么是流内元素
如果一个元素是浮动的,绝对定位的或者是根元素,那么它就是流外元素。如果一个元素不是流外的,就叫流内元素。
流内块级盒,就是流内块级元素生成的一个盒。
结论1:根元素的盒子margin不会发生重叠(原因:根元素虽然是块级盒,但不是流内元素)。
举个?:根元素与body的margin不会重叠

 html {margin-top:10px;}body {margin-top:10px;}

事实:body距离视口顶部20px。

结论2: 任何浮动的、绝对定位的盒子不会与任何其他盒子的margin合并(原因:它们是流外块级盒)。

举个?:两个绝对定位的盒子,不会发生margin重叠。

<style>.div1 {width: 100px;height: 100px;position: absolute;background: red;margin-bottom: 10px;top: 0;}.div2 {width: 100px;height: 100px;position: absolute;background: yellow;margin-top: 10px;top: 100px;}
</style><div class="div1"></div>
<div class="div2"></div>

在浏览器一看,咦,两个div间距刚好是10px,这不是发生margin重叠了吗?no,no,no。如果此时,改变其中一个div的margin值,都不会影响任何一个div的布局。通俗的讲就是,把绝对定位的盒子比作飞起来的盒子,那么这两个飞起来的盒子,一定处于不同高度,因此,不管这个盒子如何移动,都不会影响任何一个飞起来的盒子。

什么是格式化上下文? 常规流中的盒属于一个格式化上下文,可能是块或是内联,但不能都是(既是块又是内联)。块级盒参与块格式化上下文。内联级盒参与内联格式化上下文 。

新建块级格式化上下文(BFC)的条件

  • 浮动元素,float除了none以外的值。
  • 绝对定位元素,position(absolute,fixed)
  • display 为以下其中之一的值 inline-blocks,table-cells,table-captions
  • overflow 除了 visible 以外的值(hidden,auto,scroll)
  • 注意:“display:table” 本身并不产生 BFC,而是由它产生匿名框,匿名框中包含 “display:table-cell” 的框会产 BFC。

在一个块格式化上下文中,盒在竖直方向一个接一个地放置,从包含块的顶部开始。两个兄弟盒之间的竖直距离由margin属性决定。同一个块格式化上下文中的相邻块级盒之间的竖直margin会合并。

结论3:建立了新的块级格式化上下文的元素的margin不会与它们的流内子集合并。(原因:不在同一个块级格式化上下文)

举个?:overflow不为‘visible’的元素,不会与它的流内子级合并。

.father {width: 100px;height: 100px;background: red;margin-top: 10px;}.child {width: 50px;height: 50px;background: yellow;margin-top: 20px;}
<div class="father"><div class="child"></div>
</div>

这种情况是,father的overflow是‘visible’,发生了margin重叠,father向下偏移20px,如下图所示。

如果把father的overflow的值改为不是‘visible’的值,那么就不会发生margin重叠,如下图所示。

2.没有行盒(line box),没有空隙,没有padding并且没有border把它们隔开。

意思就是说,如果两个margin之间有东西隔着,它们并不是紧挨着一起,那么就不会发生margin重叠。

举个?:父元素有border,父子元素不会发生margin重叠。

<style>.father{width: 100px;height: 100px;background: red;margin-top: 10px;}.child {width: 100px;height: 50px;background: yellow;margin-top: 20px;}
</style><div class="father">
<div class="child"></div>
</div>

这种情况是,父子元素margin没有被隔开的。因此,margin重叠了。如图所示:

如果给父元素顶部添加1像素的border,那么父子元素margin被边框隔离,此时不会发生margin重叠。如图所示:

此时child距离father顶部20px;

在举个例子:空div的margin自身重叠

<style>.div1 {width: 100px;margin-top: 100px;margin-bottom: 100px;}.div2 {width: 100px;height: 100px;background: red;}
</style>
<div class="div1">
</div>
<div class="div2"></div>

如果空div的上下margin没有隔开,就会发生重叠,如图所示:

红色div向下偏离了100px,而不是200px,因为空div发生了margin重叠。如果给空div加上padding-top=10px,就不会发生margin重叠,如图所示:

此时红色div向下偏移了210px(100+100+10)。

3.最后一个流内子级的bottom margin和它的父级的bottom margin,如果父级的高度的计算值为’auto’。

<style>.father {width: 100px;margin-bottom: 100px;}.child {width: 100px;height: 100px;margin-bottom: 150px;background: red;}.sibling {width: 100px;height: 100px;background: yellow;}
</style>
<div class="father"><div class="child"></div>
</div>
<div class="sibling"></div>

此时father元素高度是auto,father的margin-bottom与child的margin-bottom,发生了重叠,因此,sibling距离father150px;
如图所示:

如果此时给father设置height:100px;那么father的margin-bottom就不会和child的margin-bottom发生重叠。此时sibling与father的垂直距离,只跟它们的margin值有关,与child的margin值无关。如图所示:

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

 <style>.div1 {width: 100px;margin-top: 100px;margin-bottom: 100px;}.div2 {width: 100px;height: 100px;background: red;}
</style>
<div class="div1">
</div>
<div class="div2"></div>

这种情况下,div1没有建立一个新的格式化上下文并且height:auto,也没有流内子级。div1自身div就重叠了,div2便宜100px。如图所示:

如果将div1的overflow设置为’不为visible’的值,或添加流内子级1(不能是空标签,否则margin照样重叠),或添加height值。此时,margin都不会重叠。这个就不贴图片了。

总结

把margin重叠的条件分析了一遍,就得到了margin不重叠的情况。
我的总结是:只要两个margin被隔开了,就一定不会发生margin重叠。可以是上下border隔开,可以是被上下padding隔开,也可以是被高度隔开,可以是被流内子级隔开,可以被空隙(空隙的产生与clear有关)隔开,可以被新建立的格式化上下文隔开。

一个浮动的盒与任何其它盒之间的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(如果有的话)都合并了。
    如果盒的top和bottom margin相邻,那么可能会被彻底合并(collapse through)
    margin。此时,元素的位置取决于与其它margin被合并了的元素的关系
    如果该元素的margin与其父级的top margin合并了,盒的top border边被定义为与其父级的相同
    否则,要么该元素的父级没有参与margin合并,要么只涉及其父级的bottom margin。如果该元素的bottom border不为0的话,其top border边的位置将正常显示(the same as it would have been)。
    注意,已被彻底合并了的元素的位置不影响其它margin被合并的元素的位置,只有在布局这些元素的后代时,才需要top border边的位置。

好了margin不重叠的分析就到此结束,如有错误,欢迎指出。

作者:打铁大师
链接:https://www.jianshu.com/p/52a253eb90cb
来源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

margin重叠问题相关推荐

  1. CSS 外边距(margin)重叠及防止方法

    边界重叠是指两个或多个盒子(可能相邻也可能嵌套)的相邻边界(其间没有任何非空内容.补白.边框)重合在一起而形成一个单一边界. 两个或多个块级盒子的垂直相邻边界会重合.结果的边界宽度是相邻边界宽度中最大 ...

  2. CSS外边距(margin)重叠及防止方法

    #css外边距margin重叠及防止方法CSS外边距(margin)重叠及防止方法 #1-什么是外边距margin重叠1. 什么是外边距(margin)重叠 外边距重叠是指两个或多个盒子(可能相邻也可 ...

  3. 前端学习(565):margin重叠意义

    没有margin重叠

  4. 清浮动,防止上下margin重叠(浏览器顶部空白崩溃)

    清浮动 父级添加类别! .clearfix{zoom:1;//兼容ie6,7} .clearfix:after{content:".";display: "block&q ...

  5. css margin为什么重叠,CSS 外边距(margin)重叠及防止方法

    边界重叠是指两个或多个盒子(可能相邻也可能嵌套)的相邻边界(其间没有任何非空内容.补白.边框)重合在一起而形成一个单一边界. 两个或多个块级盒子的垂直相邻边界会重合.结果的边界宽度是相邻边界宽度中最大 ...

  6. margin 重叠问题的理解

    相关知识点: 块级元素的上外边距(margin-top)与下外边距(margin-bottom)有时会合并为单个外边距,这样的现象称为"margin合 并".产生折叠的必备条件:m ...

  7. 如何理解margin重叠问题

    一.写在前面 根据w3c规范,两个margin产生折叠的必备条件: 1.必须处于常规文档流(不能是浮动和定位)的块级盒子,并且处于同一个BFC当中. 2.没有线盒,没有空隙,没有padding和bor ...

  8. CSS margin 重叠(margin collapse)

    margin 重叠(margin collapse) 首先有两个地方是我自己以前也没有注意的 非替换元素的内联元素(<span>, <code>等), 设置上下 margin ...

  9. margin重叠 及防止方法

    注:本文转载自(http://www.hujuntao.com/web/css/css-margin-overlap.html) 前段时间辞职了,然后一直处于求职的状态,面试的第一家公司是一家初创公司 ...

最新文章

  1. 【经验】对一个合格C++高级工程师(音视频方向)的要求
  2. Common Lisp 函数 require 和 provide 源代码分析
  3. mini2440:最简单的嵌入式linux驱动程序模块,mini2440:最简单的嵌入式Linux驱动程序模块 解决找不到mini2440……sample...
  4. android studio运行手机时出错怎么解决_小程序 android ios h5解决方案
  5. linux关机_3.5 开关机命令及7个运行级别《LINUX-centos7-操作系统入门到精通》
  6. The “note“ model is Samsung’s first
  7. slack 团队协作平台
  8. [oracle 10g]命令行启动ORACLE服务及顺序
  9. 开源免费的pdf文档编辑器LibreOffice
  10. Hadoop架构和原理
  11. DotNetCore CAP
  12. 崔云php_佘家村里的“茉莉香”
  13. 利用unity和steamVR完成场景漫游(五) 学习VRTK中简单案例
  14. 使用方法论报告第 5 部分:DDR4 IP 校准后硬件故障,指示存在时序问题,但时序报告中无任何违例
  15. 既生xargs何生parallel
  16. 币圈人警惕!5大错误足以摧毁你的一切
  17. 词频统计(30 分)
  18. 数据采集简繁体快速转换
  19. 编译Qtopia-1.7.0到E680g手机
  20. 五种360safe不能运行,启动,打开的解决办法。

热门文章

  1. NetToPlcSim_PLC_西门子PLC访问DEMO
  2. 杭州区块链技术与应用联合会简报
  3. Panda 用法( 基础 )
  4. Storm DRPC 使用及访问C++ Bolt问题的解决方法
  5. Android Preference详解
  6. JavaScript error: resource://gre/modules/XULStore.jsm, line 66: Error: Can‘t find profile directory
  7. 模电(二)半导体二极管
  8. nginx 配置https 代理http接口
  9. div css背景自动渐变色,div+css背景渐变色代码
  10. ildasm + ilasm + ilmerge 小试牛刀