这是前面写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. 8. String to Integer (atoi)

    题目: Implement atoi to convert a string to an integer. Hint: Carefully consider all possible input ca ...

  2. 关于Listview布局的一点经验

    1.尽量是给item一个固定高度,最外层不要设高度,里面套一层设置一个固定高度:如果用wrap_content的话,之后用alignTop等会出奇怪的问题. 2.如果要使用alignTop align ...

  3. python3实现简单爬虫功能

    本文参考虫师python2实现简单爬虫功能,并增加自己的感悟. #coding=utf-8 import re import urllib.request def getHtml(url): page ...

  4. 模块化InnoSetup依赖项安装

    原文在这里:http://www.codeproject.com/Articles/20868/NET-Framework-Installer-for-InnoSetup 源文件地址:http://w ...

  5. android 实现桌面显示内容

    //获取windowmanager 对象 WindowManager wm = (WindowManager) getApplicationContext().getSystemService(WIN ...

  6. 织梦(dedecms)系统常用全局变量调用标签及路径

    {dede:global.cfg_memberurl/} 指的是会员中心 对应/member/目录 {dede:global.cfg_cmsurl/} 对应的是网站根目录/ {dede:global. ...

  7. COOKIE&&SESSION

    ---------------------------------------------------------------------------COOKIE------------------- ...

  8. 【EF学习笔记05】----------DBContext基础查询

    遍历所有实体 //遍历所有学生 DBSet using (var db = new Entities()) { foreach (var student in db.Student) { Object ...

  9. Python学习笔记(四)字符串型

    字符串是 Python 中最常用的数据类型.我们可以使用引号('或")来创建字符串. 在最新的Python 3版本中,字符串是以Unicode编码的,也就是说,Python的字符串支持多语言 ...

  10. avalon2学习教程11数据联动

    在许多表单应用,我们经常遇到点击一个复选框(或下拉框)会引发旁边的复选框(或下拉框)发生改变,这种联动效果用avalon来做是非常简单的.因为avalon拥有经典MVVM框架的一大利器,双向绑定!绝大 ...