这是前面写postion定位时写到最后面的例子的时候发现的一个问题,于是专门写一篇随笔来解释记录一下,毕竟两个知识点同时写在一篇文章里面有点混乱的感觉。。

  上篇随笔position定位遇到的问题在这里重新展示出来,代码如下:

 <!DOCTYPE html>
<html>
<head>
<title></title>
<script type="text/javascript" src="jquery.js"></script>
<style type="text/css">
div{
width: 100px;
height: 100px;
margin-top: 20px;
background-color: red;
}
span{
position: relative;
display: block;
width: 100px;
height: 100px;
background-color: pink;
margin-top: -40px;
}
</style>
<script type="text/javascript"> </script>
</head>
<body>
<div>
<span></span>
</div>
</body>
</html>

  在现在的比较新版的浏览器的效果图如下:

  (这里粉色的height为80px;)

  现在来解释一下原因(这里遇到的一个问题是外边距合并的问题):

  collapsed margin:外边距合并。详细解释可以看:W3C官网的解释

  In CSS, the adjoining margins of two or more boxes (which might or might not be siblings) can combine to form a single margin. Margins that combine this way are said to collapse, and the resulting combined margin is called a collapsed margin.

  中文解释:在CSS中,两个或多个毗邻(父子元素或兄弟元素)的普通流中的块元素垂直方向上的 margin 会发生叠加。这种方式形成的外边距即可称为外边距叠加(collapsed margin)。

  毗邻:没有被非空内容、padding、border 或 clear 分隔开的两个元素(可以是父子关系或者兄弟关系,只要相邻即可)。

  普通流:除浮动( float )、绝对定位( absolute )外的代码。

  下面几种情况算是毗邻:

  (1)top margin of a box and top margin of its first in-flow child

    一个元素的 margin-top 和它的第一个子元素的 margin-top

  (2)bottom margin of box and top margin of its next in-flow following sibling

    普通流中一个元素的 margtin-bottom 和它的紧邻的兄弟元素的的 margin-top

  (3)bottom margin of a last in-flow child and bottom margin of its parent if the parent has ‘auto’ computed height

    一个元素( height 为 auto )的 margin-bottom 和它的最后一个子元素的margin-bottom

  (4)top and bottom margins of a box that does not establish a new block formatting context and that has zero computed ‘min-height’, zero or ‘auto’ computed ‘height’, and no in-flow children

    一个没有创建 BFC、没有子元素、height 为0的元素自身的 margin-top 和 margin-bottom

  上网找了一下图片说明一下:

  • 兄弟元素

  

  • 父子元素

  

  • 空元素

  

  • 以上三种混合

  

  

  现在可以解释最前面遇到的问题了:

  在上面的代码中,之所以父元素div和子元素span会重叠并且看到的实际高度只有80px,就是因为div的margin-top:20px;与span的margin-top:-40px;发生重叠,剩下-20px,而此时的margin-top:-20px;就会被认为是父元素div的外边距了,所以才会整体向上移动20px的距离。

(注意:这里因为两个外边距一个是负一个是正,所以刚好叠加只剩下-20px,而不是比较得到比较大的数作为外边距的值)

* 两个相邻的外边距都是正数时,折叠结果是它们两者之间较大的值
* 两个相邻的外边距都是负数时,折叠结果是两者绝对值的较大值
* 两个外边距一正一负时,折叠结果是两者的相加的和

  

  应该如何避免这种情况:

  官网如下说:

  • Margins between a floated box and any other box do not collapse (not even between a float and its in-flow children).
  • Margins of elements that establish new block formatting contexts (such as floats and elements with 'overflow' other than 'visible') do not collapse with their in-flow children.
  • Margins of absolutely positioned boxes do not collapse (not even with their in-flow children).
  • Margins of inline-block boxes do not collapse (not even with their in-flow children).
  • The bottom margin of an in-flow block-level element always collapses with the top margin of its next in-flow block-level sibling, unless that sibling has clearance.
  • The top margin of an in-flow block element collapses with its first in-flow block-level child's top margin if the element has no top border, no top padding, and the child has no clearance.
  • The bottom margin of an in-flow block box with a 'height' of 'auto' and a 'min-height' of zero collapses with its last in-flow block-level child's bottom margin if the box has no bottom padding and no bottom border and the child's bottom margin does not collapse with a top margin that has clearance.
  • A box's own margins collapse if the 'min-height' property is zero, and it has neither top or bottom borders nor top or bottom padding, and it has a'height' of either 0 or 'auto', and it does not contain a line box, and all of its in-flow children's margins (if any) collapse.

  即:

  • 浮动元素和其他任何元素之间不发生外边距叠加 (包括和它的子元素).
  • 创建了 BFC 的元素不会和它的子元素发生外边距叠加
  • 绝对定位元素和其他任何元素之间不发生外边距叠加(包括和它的子元素).
  • inline-block 元素和其他任何元素之间不发生外边距叠加 (包括和它的子元素).
  • 普通流中的块级元素的 margin-bottom 永远和它相邻的下一个块级元素的 margin-top 叠加(除非相邻的兄弟元素clear)
  • 普通流中的块级元素(没有 border-top、没有 padding-top )的 margin-top 和它的第一个普通流中的子元素(没有 clear )发生 margin-top 叠加
  • 普通流中的块级元素( height 为 auto、min-height 为 0、没有 border-bottom、没有 padding-bottom )和它的最后一个普通流中的子元素(没有自身发生 margin 叠加或 clear )发生 margin-bottom 叠加
  • 如果一个元素的 min-height 为 0、没有 border、没有 padding、高度为 0 或者 auto、不包含子元素,那么它自身的外边距会发生叠加

  总结:

  • 兄弟元素间设置 float 或 inline-block 或 absolute
  • 为父元素设置 BFC 或 padding 或 border
  • 设置margin时最好用同一个方向,要不都 top 要不都 bottom.

2016-8-5补充:

  当父元素里面包含的两个子元素是浮动的话,那么该父元素不会包裹子元素,即不会被子元素撑开,解决的方式就是:为父元素设置overflow:hidden或浮动父元素。采用这种方式的根本原因在于创建BFC的元素,子浮动元素也会参与其高度计算,即不会产生高度塌陷问题。实际上只要让父元素生成BFC即可,并不只有这两种方式。

哪些情况会产生BFC:

  • 根元素

  • float属性不为none

  • position为absolute或fixed

  • display为inline-block, table-cell, table-caption, flex, inline-flex

  • overflow不为visible

  参考资料:css框模型

  

关于collapsed margin(外边距合并)的更多相关文章

  1. 为什么margin-top不是作用于父元素【margin外边距合并问题】

    coding时发现margin-top居然没作用于本元素上,而是作用到了父元素上. 原来是margin外边距合并导致的.以下是网上搬运来的知识: margin外边距合并详解:外边距合并现象在网页布局中 ...

  2. 关于margin外边距合并的问题

    一 .兄弟元素margin外边距合并演示   当两个垂直方向相邻的兄弟元素都为常规流块盒,他们之间垂直方向的外边距不是两者之和,而是取两者中的最大值.这种现象被称为相邻的兄弟元素垂直方向外边距合并. ...

  3. CSS Margin外边距合并

    应该知道这点东西的!!! 可是偏偏记不住! 外边距合并会发生在以下两种情况下: 1 垂直出现的两个拥有外边距的块级元素. div1 { margin-bottom: 20px; } div2 { ma ...

  4. margin 外边距合并问题

    一.兄弟元素的外边距合并 效果图如下:(二者之间的间距为100px,不是150px) 二.嵌套元素的外边距合并 对于两个嵌套关系的元素,如果父元素中没有内容或者内容在子元素的后面并且没有上内边距及边框 ...

  5. margin外边距合并问题以及解决方式

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  6. 转载:margin外边距合并问题以及解决方式

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  7. “margin塌陷” 嵌套盒子外边距合并现象

    来源于官方文档对于外边距合并的解释: 注释:只有普通文档流中块框的垂直外边距才会发生外边距合并.行内框.浮动框或绝对定位之间的外边距不会合并. 出现外边距塌陷的三种情况: 1.相邻兄弟元素之间 若两者 ...

  8. CSS外边距合并(塌陷/margin越界)

    原文 简书原文:https://www.jianshu.com/p/5f18f12cd162 大纲 1.什么是外边距合并?(折叠外边距) 2.外边距带来的影响 3.折叠的结果 4.产生折叠的原因 5. ...

  9. margin显示怪异,外边距合并问题

    很多时候我们使用两个div,内层的div设置文字,需要垂直居中与上层div,但是怎么设置样式都不行,vertical-align:middle也不行. 代码: <div style=" ...

随机推荐

  1. Sql语句查看表结构

    快速查看表对的就说明,及表字段描述及字段类型 --表描述 SELECT tbs.name 表名,ds.value 描述 FROM sys.extended_properties ds LEFT JOI ...

  2. CyclicBarrier类合唱演绎

    package a.jery; import java.util.concurrent.CyclicBarrier; import java.util.concurrent.ExecutorServi ...

  3. loadrunner11遇到的问题汇总及相应的解决方案(持续更新)

    1.在此界面点击Run Load Tests提示: "Can not save the license information because access to the registry  ...

  4. Matrix的一些知识

    1.什么是ColorMatrix ColorMatrix是一个颜色矩阵,它定义了一个 4*5 的float[]类型的矩阵 颜色矩阵,而图像的 RGBA 值则存储在一个5*1的颜色分量矩阵C中 所以为了 ...

  5. 纸上谈兵:左倾堆(leftist heap)

    作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 我们之前讲解了堆(heap)的概念.堆是一个优先队列.每次从堆中取出的元素都是堆中 ...

  6. mongodb 的安装和使用

    官方网址 http://www.mongodb.org 1.下载mongodb-win32-i386-latest.zip 解压 mongodb 3.1.5 需要 win7 下 下载安装内存补丁 ht ...

  7. cin判断读取结束 C++语言

    cin是C++的输入流,可以通过>>进行读取. 判断读取结束,一般有两种方法,具体取决于与输入的约定. 1 以特殊值结尾. 如输入整数,以-1结束,那么当读到-1的时候,就确定读取结束了. ...

  8. Provisional headers are shown,本地测试成功,服务器运行却失败

    基于MVC的项目 具体情况是一个页面在访问的时候进不了首页,但详细页面却可以进去 下面说说解决方法和思路,以便找出问题所在 第一:把服务器代码下载到本地运行,代码是否出错,出错了,问题找到了,没出错接 ...

  9. CentOS网络配置详解

    转载于CentOS中文站:http://www.centoscn.com/CentOS/2015/0507/5376.html一.配置文件详解 在RHEL或者CentOS等Redhat系的Linux系 ...

  10. mysql之字符编码问题

    mysql编码分为服务端编码和客户端编码两大类字段编码, 表编码, 数据库编码这些编码都属于服务端编码,服务端编码决定你可以存哪些字符以及这些字符要哪种规则排序.字段编码优先级最高. 你插入用什么码属 ...