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

  • 包含在父元素中的子元素设置了浮动,子元素高度变化的时候父元素的高度没有随着变化,就是没有被撑高,父元素仍然是原来设置的那个高度
  • 包含在父元素中的子元素,子元素的宽高没有设置,而是通过自身的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. 改变this指针的apply,call,bind的区别

    apply.call 在 javascript 中,call 和 apply 都是为了改变某个函数运行时的上下文(context)而存在的,换句话说,就是为了改变函数体内部 this 的指向. Jav ...

  2. AIX 5L 系统管理技术 —— 存储管理——卷组

    卷组 在安装系统时,就会创建一个rootvg卷组.包含自带硬盘(内置硬盘)和系统逻辑卷,一个系统只能有一个rootvg卷组.一般情况下rootvg卷组最好只包含自带硬盘. 一.创建卷组 在创建卷组之前 ...

  3. Android tween 动画 XML 梳理

    前言: Tween动画是展现出旋转.渐变.移动.缩放的这么一种转换过程,即补间动画.Tween动画有两种定义方式:XML形式,编码形式.这次主要来梳理XML的方式配置动画 (1)XML定义动画,按照动 ...

  4. Android中使用Handler造成内存泄露的分析和解决

    什么是内存泄露?Java使用有向图机制,通过GC自动检查内存中的对象(什么时候检查由虚拟机决定),如果GC发现一个或一组对象为不可到达状态,则将该对象从内存中回收.也就是说,一个对象不被任何引用所指向 ...

  5. 使用filter获取http请求的出参以及入参

    首先 我们的目的是做一个拦截器 能够对http请求做profiler,能够记录本次的调用情况,这里说下如何从http请求中获取到出参的问题. 方案一:参照http://blog.csdn.net/wu ...

  6. C# date format 使用C#格式化时间

    DateTime dt = DateTime.Now; //    Label1.Text = dt.ToString();//2005-11-5 13:21:25 //    Label2.Text ...

  7. CodeSmith 介绍

    代码生成器作用 中国有句古语叫做“工欲善其事,必先利其器”,用通俗的话来说就是“磨刀不误砍柴功”,古人的这些话告诉我们:要把事情做好,事先应该准备合适的工具.工具不仅仅包括器具, 还包括思想.理论.经 ...

  8. 横向不间断滚动DIV

    横向不间断滚动DIV,5个一组,js控制,自动生成任意组显示 <!DOCTYPE html> <html> <head> <meta http-equiv=& ...

  9. MVC系列2-Model

    上一篇我讲了ASP.MET MVC的基础概念,我相信从上一篇,我们可以知道MVC的执行过程.这一篇我们开始讲解Model.我们知道,在我们的应用程序中,大多时候是在遵循业务逻辑通过UI操作数据.所以这 ...

  10. 1.Linux系统安装

    Linux系统安装系统分区(磁盘分区) 主要管理:文件和目录分类:主分区:最多有4个 扩展分区:1个扩展分区 和主分区最多4个 存放逻辑分区 逻辑分区:存放数据 格式化:高级格式化(逻辑格式化) 写入 ...