在平时处理样式的过程中,会出现各种问题。比如:

  • 包含在父元素中的子元素设置了浮动,子元素高度变化的时候父元素的高度没有随着变化,就是没有被撑高,父元素仍然是原来设置的那个高度
  • 包含在父元素中的子元素,子元素的宽高没有设置,而是通过自身的margin值来根据父元素的大小来设置自身的宽高,但是实际上顶部的margin却跟父元素重叠在一起
  • 元素明明设置成了块级,但是定义高度一直都不是想要的高度
  • 跟相邻元素用margin隔开,但是实际上margin的值跟设定的不同。
  • 在低版本浏览器中(ie6,7),block元素设置成inline-block后没有效

盒子模型

前面提的问题,基本上都是与css中的盒模型相关的。

Source: w3c

盒子的宽度

= margin-left + margin-right + border-left + border-right + padding-left + padding-right + width

盒子的高度

= margin-top + margin-bottom + border-top +border-bottom + padding-top + padding-bottom + height

注意:

  • margin是透明的没有颜色,border默认与文字颜色一直,padding的颜色同元素的背景色。
  • margin的垂直属性,也就是margin-top, margin-bottom,在inline的元素中不起作用。margin是可以有负值的。
  • padding属性无论是在inline还是block元素中都会有效,不过padding是没有负值的。

Margin外边距

box.html这里,其中inner跟outer的margin-top, margin-right发生了重叠,也就是子元素跟父元素的margin会发生重叠;outer的margin-bottom跟outer2的margin-top发生了重叠,也就是相邻元素的margin会发生重叠。

标准

在css2.1的标准是这么说的 (这里进入

" 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中,两个或者更多(有可能是同辈或者是后辈)毗邻盒子的外边距会重叠形成一个单一的边距。这种方式生成外边距的方式称为坍塌(叠加),这个结果形成的外边距叫做坍塌(叠加)外边距。

简单分析一下:

发生外边距重叠的情况,首先是要两个盒子毗邻,它们的外边距才发生重叠。这里面说的毗邻指的是什么呢?后面有解释,是两个盒子在正常流中的毗邻。

标准里的不发生重叠的情况

水平方向上永远不会发生重叠。

垂直方向上,下列情况不会发生重叠:

  • 根元素的外边距不会发生重叠
  • 如果拥有"空隙clearance"(也就是除了clear:none以外的值)的元素的上下外边距毗邻,它的边距会跟毗邻的元素发生重叠,但是形成的重叠不会再跟父元素的底部外边距发生重叠。

什么是空隙clearance?

*(Clear's) Values other than 'none' potentially introduce clearance. (clear除了none以外的值可能产生空隙)

* Clearance inhibits margin collapsing and acts as spacing above the margin-top of an element. It is used to push the element vertically past the float.(空隙会抑制外边距坍塌,并且会表现为在外边距的顶部有一段空白。这是用来将元素垂直浮动的)

标准里发生重叠的情况

什么才是两个外边距毗邻呢(也就是怎样才会发生重叠)?

  • 处于同一个块级格式上下文中的,同属正常流的块级盒子(这两个元素是没有脱离正常流的块级盒子,而且同在一个块级格式化上下文中)。
  • 两个元素没有被line-box, clearance, padding, border分开。
  • 两个元素都是垂直边缘毗邻,符合下列情况中的一种
    • 盒子的顶部外边距(margin-top),和它的第一个处于正常流子元素的顶部外边距(margin-top)
    • 盒子的底部外边距(margin-bottom),和它的下一个处于正常流中的兄弟元素的顶部外边距(margin-top)
    • 处于正常流中的最后一个元素的底部外边距(margin-bottom),和它高度height为auto的父元素的底部外边距(margin-bottom)
    • 没有触发块级格式上下文,min-height为0,或者height为auto,以及没有处于正常流的子元素的盒子的margin-top,和margin-bottom

所谓的外边距坍塌,就是与另一个的外边距毗邻,只要是四个外边距中的任意一个即可。

注意:外边距坍塌会发生在任何的元素上,不单只是兄弟元素或者祖先元素。

上面的规则的意思就是(也就是具体规则):

  • 浮动盒子跟任意其他盒子的外边距不会叠加(即使是浮动元素跟它的正常流子元素)。
  • 具有块级格式上下文的元素(就比如除overflow: visiable值之外的元素)跟它的处于正常流的子元素不会发生外边距叠加。
  • 具有绝对定位的盒子的外边距不会发生叠加。(以及他们的正常流子元素)
  • 行内块级(inline-block)盒子不会发生外边距叠加。(以及他们的正常流子元素)。
  • 处于正常流的块级元素的底部外边距(margin-bottom)总是会跟他的下一个兄弟正常流的块级元素的顶部外边距(margin-top)叠加,除非这个兄弟元素有空隙(clearance).
  • 正常流块级元素的margin-top会跟它的第一个正常流块级子元素的margin-top叠加,如果这个元素没有border-top,没有padding-top,以及它的子元素没有空隙(clearance)。
  • 一个正常流的块级盒子若是height:auto或min-height:0,他的margin-bottom会跟最后一个正常流子元素的margin-bottom叠加,如果这个盒子没有padding-bottom或者border-bottom,并且子元素的margin-bottom没有跟有空隙(clearance)的margin-top叠加的话。
  • 一个盒子如果min-height:0,没有border-top或border-bottom,也没有padding-top或padding-bottom,也没有包含一个line box,且height:0 或height: auto,那么他的外边距会叠加,所有正常流子元素的外边距都会叠加。

如果发生外边距叠加,这个产生的外边距的值是这两个外边距中最大的那个。如果有负的外边距,那么值就是用最大的负的外边距的跟最大的正的外边距的相加。如果没有正值外边距,那么就是绝对值的最大值减去0.

Demo

不发生重叠的情况

前面翻译了css2.1中关于margin发生重叠的各种情况。但是大部分的实际工作中,为了更好的更精准的进行布局,我们一般是要避免margin发生重叠的。前面也提到了,水平方向上的margin是永远不会重叠的,所以接下来通过实际操作来看一下如何避免毗邻的外边距重叠。

浮动盒子跟任意其他盒子的外边距不会叠加(即使是浮动元素跟它的正常流子元素)。

参考demo1demo2

在demo1中,outer浮动,inner是outer的in-flow(正常文档流)的子元素,所以outer的margin与inner的margin没有发生重叠。

在demo2中,outer,outer2均设置了浮动,触发了BFC,所以outer和outer2的外边距不会叠加。

浮动其实是脱离正常的文档流了,发生重叠的三个条件都是在正常的文档流中触发的,而且float是会触发BFC的,所以浮动元素是不会发生重叠的。

具有块级格式上下文(BFC)的元素(就比如除overflow: visiable值之外的元素)跟它的处于正常流的子元素不会发生外边距叠加。

块级格式上下文(block formatting context,后文简称BFC)是css2.1里描述的,在css3里面描述成了flow root。浮动元素和position除了relative和static之外的值,非块级盒子的块级容器(例如 inline-blocks, table-cells, 和 table-captions),以及overflow除了visible之外的值,都会触发BFC,其他的后续再详细分析。

参考在demo1中的outer和inner。Outer触发了BFC,所以与子元素inner的外边距没有重叠。

具有绝对定位的盒子的外边距不会发生叠加。(以及他们的正常流子元素)

参考demo3

绝对定位也是脱离了正常的文档流的,跟浮动一样,违背了触发外边距重叠的条件,所以绝对定位也是肯定不会发生外边距重叠的。

行内块级(inline-block)盒子不会发生外边距叠加。(以及他们的正常流子元素)。

参考demo4

如果拥有"空隙clearance"(也就是除了clear:none以外的值)的元素的上下外边距毗邻,它的边距会跟毗邻的元素发生重叠,但是形成的重叠不会再跟父元素的底部外边距发生重叠。

参考demo5

如果父元素拥有border或padding,它的margin不会与子元素的发生重叠。

参考demo6

发生重叠的情况

如果拥有"空隙clearance"(也就是除了clear:none以外的值)的元素的上下外边距毗邻,它的边距会跟毗邻的元素发生重叠

参考demo5

处于正常流的块级元素的底部外边距(margin-bottom)总是会跟他的下一个兄弟正常流的块级元素的顶部外边距(margin-top)叠加,除非这个兄弟元素有空隙(clearance).

参考box

正常流块级元素的margin-top会跟它的第一个正常流块级子元素的margin-top叠加,如果这个元素没有border-top,没有padding-top,以及它的子元素没有空隙(clearance)。

参考box

*新问题,outer2有padding: 10px; 内部的span也有一个padding: 10px;但是span的padding-top跟outer2的padding-top重叠了诶。如果span没有定义padding-top的话,那就是没有重叠。这是个新问题,稍后看看padding的定义吧。

一个正常流的块级盒子若是height:auto或min-height:0,他的margin-bottom会跟最后一个正常流子元素的margin-bottom叠加,如果这个盒子没有padding-bottom或者border-bottom,并且子元素的margin-bottom没有跟有空隙(clearance)的margin-top叠加的话。

参考demo7。后半句,如果有子元素跟有clearance的元素叠加了的话,那么就不会跟父元素再发生叠加了,例如demo5.

一个盒子如果min-height:0,没有border-top或border-bottom,也没有padding-top或padding-bottom,也没有包含一个line box,且height:0 或height: auto,那么他的外边距会叠加,所有正常流子元素的外边距都会叠加。

参考demo7

margin-collapse基本上就是上述所说的了,看起来很多的样子,其实也没有那么复杂,平时用到margin的时候留点心就可以了。

关于margin的一些问题的更多相关文章

  1. 金融量化分析【day112】:因子选股

    一.因子选股基础 二.因子选股策略实现代码 # 导入函数库 import jqdata import psutil #初始化函数,设定基准等等 def initialize(context): set ...

  2. 理解CSS外边距margin

    前面的话   margin是盒模型几个属性中一个非常特殊的属性.简单举几个例子:只有margin不显示当前元素背景,只有margin可以设置为负值,margin和宽高支持auto,以及margin具有 ...

  3. 深入理解CSS中的margin负值

    前面的话 margin属性在实际中非常常用,也是平时踩坑较多的地方.margin折叠部分相信不少人都因为这样那样的原因中过招.margin负值也是很常用的功能,很多特殊的布局方法都依赖于它.它看似简单 ...

  4. margin折叠-从子元素margin-top影响父元素引出的问题

    正在做一个手机端电商项目,顶部导航栈的布局是一个div包含一个子div,如果给在正常文档流中的子div一个垂直margin-top,神奇的现象出现了,两父子元素的边距没变,但父div跟着一起往下走了! ...

  5. CSS margin详解

    以下的分享是本人最近几天学习了margin知识后,大有启发,感觉以前对margin的了解简直太浅薄.所以写成以下文章,一是供自己整理思路:二是把知识分享出来,避免各位对margin属性的误解.内容可能 ...

  6. 基于Caffe的Large Margin Softmax Loss的实现(中)

    小喵的唠叨话:前一篇博客,我们做完了L-Softmax的准备工作.而这一章,我们开始进行前馈的研究. 小喵博客: http://miaoerduo.com 博客原文:  http://www.miao ...

  7. 基于Caffe的Large Margin Softmax Loss的实现(上)

    小喵的唠叨话:在写完上一次的博客之后,已经过去了2个月的时间,小喵在此期间,做了大量的实验工作,最终在使用的DeepID2的方法之后,取得了很不错的结果.这次呢,主要讲述一个比较新的论文中的方法,L- ...

  8. 由css reset想到的深入理解margin及em的含义

    由css reset想到的深入理解margin及em的含义 原文地址:http://www.ymblog.net/content_189.html 经常看到这样语句,*{ margin:0px;pad ...

  9. 探究负边距(negative margin)原理

    W3C规范在介绍margin时有这样一句话: Negative values for margin properties are allowed, but there may be implement ...

  10. overflow:hidden与margin:0 auto之间的冲突

    相对于父容器水平居中的代码margin:0 auto与overflow:hidden之间存在冲突.当这两个属性同时应用在一个DIV上时,在chrome浏览器中将无法居中.至于为啥我也不明白.

随机推荐

  1. UVALive 7146 Defeat the Enemy(贪心+STL)(2014 Asia Shanghai Regional Contest)

    Long long ago there is a strong tribe living on the earth. They always have wars and eonquer others. ...

  2. SASS 初学者入门

    SASS 初学者入门 Sass 是什么? Sass 是Syntactically Awesome Stylesheete Sass的缩写,是由Hampton Catlin开发的. Sass可以简化你的 ...

  3. php开发客服系统(持久连接+轮询+反向ajax 转载 http://www.tuicool.com/articles/2mU7v2R)

    php开发客服系统( 下载源码 ) 用户端(可直接给客户发送消息) 客服端(点击用户名.即可给该用户回复消息) 讲两种实现方式: 一:iframe + 服务器推技术comet(反向ajax,即服务器向 ...

  4. Elasticsearch 聚合

    桶(bucket)聚合 满足条件的结果集合.桶可以嵌套 标(metric)聚合 满足条件的结果集合的一些指标.如count,max等.

  5. SecureCRT:保存输出日志的方法

    处理地址: http://blog.sina.com.cn/s/blog_64c1dd210101gzgz.html 或者: http://renchen.blog.51cto.com/4531967 ...

  6. Magento-找出没有图片的产品

    最近维护网站,发现网站的产品很多都没有图片显示,看了一下是因为没有在后台勾选图片,就是 image small_image  thumbnail 这三项,就算有图片如果没有勾选的话也不会显示出来,产品 ...

  7. opencv的学习笔记5

    总结原博文中的一些边缘检测算子和滤波器.(Canny算子,  Sobel算子,  Laplace算子以及Scharr滤波器) 首先,一般的边缘检测包括三个步骤: 1)滤波:边缘检测的算法主要是基于图像 ...

  8. 关于缺少nvToolsExt64_1.lib时的PhysX的处理

    我本人之所以缺少这个文件是因为我的PhysX如果你的PhysX是从UE4源代码中提取的,那么可能会出现如下错误,提示找不到nvToolsExt64_1.lib(本机是64bit的操作系统) 那就执行u ...

  9. Windows平板优化设置

    低于千元的windows平板,和iPad差异主要在于做工方面,以及Modern软件的欠缺,续航约5小时,但其可玩性和扩展性更好. 若将其视为平板附送了桌面电脑的功能,花费一定时间容易定制成适合个人使用 ...

  10. iOS 多语言的切换

    一.添加应用程序需要支持的国际语言 二.新建一个Localizable.strings文件,作为多语言对应的词典,存储多种语言 三.在Localizable.strings的对应文件以键值对的形式配置 ...