平时在工作中,总是有一些元素之间的边距与设定的边距好像不一致的情况,一直没明白为什么,最近仔细研究了一下,发现里面有学问:垂直元素之间的margin有有互相重叠的情况;新建一个BFC后,会阻止元素与外界元素的重叠现象。

  先了解几个概念:可替换元素、不可替换元素(non-replaced element)、包含块(containing block)、块级格式化上下文(BFC)。

可参考css2.1 中文规范

1、可替换元素与不可替换元素

  根据css1 中所述:所谓可替换元素就是浏览器根据元素的标签和属性,来决定元素的具体显示内容。例如浏览器会根据<img>标签的src属性的值来读取图片信息并显示出来,而如果查看(x)html代码,则看不到图片的实际内容;又例如根据<input>标签的type属性来决定是显示输入框,还是单选按钮等。html中的<img>、<input>、<textarea>、<select>、<object>都是替换元素。而现在,这个概念已经发生了变化,在新的规范中,html5涉及到的<video>、<canvas>、<menu>元素也被认为是替换元素。因此可以把“替换”理解为“嵌入”

  替换元素就可以理解为需要一些外部内容来嵌入它的空间的元素。

  而不可替换元素(non-replaced element)就是不需要外部内容来填充它的空间的元素。

2、包含块(containing block

  在 CSS2.1 中,很多框的定位和尺寸的计算,都取决于一个矩形的边界,这个矩形,被称作是包含块( containing block )。 一般来说,(元素)生成的框会扮演它子孙元素包含块的角色;我们称之为:一个(元素的)框为它的子孙节点建造了包含块。包含块是一个相对的概念,每个框关于它的包含块都有一个位置,但是它不会被包含块限制;它可以溢出(包含块)。包含块上可以通过设置 ‘overflow’ 特性达到处理溢出的子孙元素的目的。

3、块级元素和行内级元素

  块级元素:当元素的CSS属性displayblocklist-item或 table时,它是块级元素 block-level。块级元素会生成块级盒,块级盒参与块格式化上下文

     行内级元素:当元素的 CSS 属性 display 的计算值为 inlineinline-block 或 inline-table 时,称它为行内级元素

4块级格式化上下文(BFC)

  BFC,英文全称叫做Block Formatting contexts,中文叫块级格式化上下文。可以将它理解为一个箱子,这个箱子中的元素与外部元素隔离,箱子里的元素不会影响外部的元素,也不受外部元素的影响(利用这个特性可以消除浮动元素对其非浮动的兄弟元素和其子元素带来的影响)。BFC中只有块级水平的盒子参与(block-level box:display 属性为 block, list-item, table 的元素,会生成 block-level box)

BFC布局规则

l   内部的Box会在垂直方向,一个接一个地放置。

l   Box垂直方向的距离由margin决定。属于同一个BFC的两个相邻Box的margin会发生重叠

l   每个元素的margin box的左边, 与包含块border box的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如 此。

l   BFC的区域不会与float box重叠。

l   BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。

l   计算BFC的高度时,浮动元素也参与计算。

如何触发或建立一个BFC?

  W3C中定义: 浮动元素和绝对定位元素,非块级盒子的块级容器(例如 inline-blocks, table-cells, 和 table-captions),以及overflow值不为“visiable”的块级盒子,都会为他们的内容创建新的BFC(这时这个元素中的内容就同处在一个BFC中)。

当给某一元素添加以下样式中的任意一个时,就触发了BFC。

l   float: left/right/inherit  也就是除none以外的浮动元素

l   position: absolute/fixed 绝对定位元素,fixed是absolute的一个子类,也属于绝对定位

l   display: inline-block、table-cell、table-captions 需要注意的是display: table本身不可以触发BFC,但是由于table会产生匿名盒,而匿名盒的display: table-cell特性会触发BFC,产生新的格式化上下文。(匿名盒:CSS引擎自动生成的盒子,没有名字,不能被 CSS 选择符选中,不能被 CSS 选择符选中意味着不能用样式表添加样式。这意味着所有继承的 CSS 属性值为 inherit ,所有非继承的 CSS 属性值为 initial

l   overflow: hidden/auto/scroll/inherit

了解了以上概念后,我们再来看margin

margin的用途

margin的基本用途就是控制元素与周围其他元素的间隔。

margin的用法

margin通过使用单独的属性,可以对上、右、下、左的外边距进行设置。即:margin-top、margin-right、margin-bottom、margin-left;也可以使用简写的外边距属性同时改变所有的外边距:margin: top right bottom left;

margin的取值

margin的值类型有:auto | length | percentage,

1、如果设置为auto,取值如下

常规流中的块级元素的margin设置为auto时,则margin-left、margin-right的值相等。这个可以用来居中一个块级元素

浮动的元素的margin值为auto时,它的margin-left、margin-right的取值为0

绝对定位的元素的margin值设置为auto时:如果这个元素的left、right、width都是auto,那么它的margin-left、margin-right的值为0;如果这个元素的left、right、width值不是auto,那么margin-right、margin-left的值相等;如果只有一个'margin-left'或者'margin-right'有一个是'auto',则根据公式可计算出另外一个margin的值。;除以上这几种情况外,margin-left和margin-right取值为0

W3C规范中提到的margin为auto时的取值规范

css2.1规范中提到的以下元素margin设置为auto'的水平方向的'margin-left'或者'margin-right'对应的值为'0'

l   内联的不可替换元素(non-replaced inline element):既是内联元素,又是不可替换元素,如 span, strong, i, b, em、cite

l   内联的可替换元素:如:a

l   浮动的不可替换元素(block元素和inline元素)

l   浮动的可替换元素(block元素和inline元素)

l   常规流中的不可替换的inline-block元素

l   常规流中可替换的inline-block元素

常规流中的块级不可替换元素、常规流中的块级可替换元素, 若 margin-left'和'margin-right'都是'auto',那么它们的应用值相等,(这会让该元素相对于其包含块的边水平居中)。

绝对定位的不可替换元素和绝对定位的可替换元素,取值根据一个公式得出

'left' + 'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' + 'right' = 包含块的宽度。

l   如果'left','width'和'right'全都是'auto':则'margin-left'和'margin-right'的值为0

l   如果'left','width'和'right'都不是'auto':如果'margin-left'和'margin-right'都是'auto,则他们的应用值相等(根据这个规则可以使绝对定位的元素水平居中)

l   如果'margin-left'或者'margin-right'有一个是'auto',则根据上述公式求出另外一个margin的值

l   除以上规则外,'margin-left'和'margin-right'值为0。

2、设置为length的话很好理解,就是实际设置的值,单位可以是px、em等长度值。另外margin值可以设置为负值。

3、percentage:百分比是由被应用 box 的包含块containing block的大小所决定。对于 margin-top 和 margin-bottom 也同样成立。

margin外边距重叠

外边距重叠指的是,当两个垂直外边距相遇时(有可能是同辈或者后辈),它们将形成一个外边距。重叠后的外边距的高度计算如下:

两个相邻的外边距都是正数时,重叠结果是它们两者之间较大的值

两个相邻的外边距都是负数时,重叠结果是两者绝对值的较大值

两个外边距一正一负时,重叠结果是两者的相加的和。

W3C中提到的边距重叠必要条件:

1、必须是常规文档流(不是float和绝对定位,注意绝对定位包含absolute和fixed)中的块级盒子,并且处于同一个BFC当中;

2、没有行盒-即linebox(行盒由一行中所有的内联元素所组成), 没有padding和border将他们隔开;

3、都属于垂直方向上相邻的外边距 。      

W3C中提到的边距重叠的几种情况:

1)       常规文档流中,一个盒子如果没有上补白(padding-top)和上边框(border-top),那么这个盒子的上边距会和其内部文档流中的第一个子元素的上边距合并,这个子元素不能包含间隙(clearance:样式中有clear:right|left|both)。

2)       常规文档流中,一个盒子如果没有下补白(padding-top)和下边框(border-top),那么这个盒子下边距会跟他的下一个兄弟盒子的的上边距合并,除非他们之间存在间隙(clearance)。

3)       常规文档流中,height为auto的盒子的下边距会与它的最后一个子元素的下边距合并;

4)      常规文档流中,一个盒子的高度为0并且最小高度也为0,且不包含常规文档流的子元素,并且自身没有建立新的BFC的,那么它自身的上边距和下边距会合并。

根据上面的条件,不发生外边距重叠的情况有以下几种:

1)       水平方向上永远不会发生外边距合并    

2)       垂直方向上,创建了新的BFC的元素与它的子元素的外边距不会重叠(注意区别:BFC内部的子元素与子元素之间边距是会发生折叠)

3)       一个浮动的元素不与任何元素的外边距产生重叠,包括其父元素及子元素及兄弟元素;(分析:浮动元素脱离了常规文档流,且建立了BFC,他不会影响周围其他元素、也不会被其他元素影响)

4)        overflow设置为hidden|scroll|auto的元素不会与它的子元素的外边距重叠;(分析:overflow不是visible的元素建立了BFC,他不会影响周围其他元素、也不会被其他元素影响)

5)       绝对定位的元素不与任何元素的外边距产生重叠(包括其父元素及子元素及兄弟元素)(分析,脱离了常规文档流,且建立了BFC,他不会影响周围其他元素、也不会被其他元素影响)

6)       行内块级(inline-block)元素不与任何元素的外边距产生重叠(包括其父元素及子元素及兄弟元素)(分析:行内块级元素不符合发生边距重叠的第一个必要条件‘块级盒子’,块级盒子的display属性必须是以下三种之一:'block', 'list-item', 和 'table')

外边距重叠产生的影响

盒子的显示大小= border +content+padding+正margin 值。负的 margin 值不会影响 box 的实际大小,但是负的 top 或 left 值会引起 box 的向上或向左位置移动,如果是 bottom 或 right 只会影响下面 box 的显示的参考线。

     下面是给div元素设置margin:-10px 20px -30px 40px的例子;(借鉴别人的例子)

 如果还不清楚,可以参考网上几篇有关margin的文章

1、 你是否彻底了解margin属性

                                                                                       

2由浅入深漫谈margin属性  

                                                                                       

3关于margin的一些问题 

                                                                                       

4深入理解BFC和Margin Collapse

另外一篇文章介绍了负margin的几个用途,我知道你不知道的负margin

什么时候用margin,什么时候用padding

  何时应当使用margin:需要在border外侧添加空白时。空白处不需要背景(色)时。上下相连的两个盒子之间的空白,需要相互抵消时。如15px + 20px的margin,将得到20px的空白。

  何时应当时用padding:需要在border内测添加空白时。空白处需要背景(色)时。上下相连的两个盒子之间的空白,希望等于两者之和时。如15px + 20px的padding,将得到35px的空白。

css中margin重叠和一些相关概念(包含块containing block、块级格式化上下文BFC、不可替换元素 non-replaced element、匿名盒Anonymous boxes )的更多相关文章

  1. CSS中margin边界叠加问题及解决方案

    你对CSS的margin边界叠加的概念是否了解,这里和大家分享一下,当一个元素出现在另一个元素上面时,第一个元素的底边界与第二个元素的顶边界发生叠加. CSS的margin边界叠加深度剖析 边界叠加简 ...

  2. CSS中margin边界叠加问题及解决方案(转)

    边界叠加简介 边界叠加是一个相当简单的概念.但是,在实践中对网页进行布局时,它会造成许多混淆.简单地说,当两个垂直边界相遇时,它们将形成一个边界.这个边界的高度等于两个发生叠加的边界的高度中的较大者. ...

  3. CSS中margin和padding的区别

    在CSS中margin是指从自身边框到另一个容器边框之间的距离,就是容器外距离.在CSS中padding是指自身边框到自身内部另一个容器边框之间的距离,就是容器内距离. 下面讲解 padding和ma ...

  4. CSS中margin属性

    css中margin块级元素的垂直相邻外边距会合并,比如 方框的上下外边距并不是2px,而是合并为1px了. 设置float属性就可以避免这种同级元素边距合并

  5. css 块级格式化上下文(BFC)

    一.块级格式化上下文(BFC) 1.什么是块级格式化上下文? Block Formatting Contexts (BFC,块级格式化上下文)就是一个块级元素 的渲染显示规则 (可以把 BFC 理解为 ...

  6. 使用CSS中margin和padding的基础和注意事项

    在CSS中,margin和padding是页面布局的主要属性,如何灵活有效使用对于基于DIV+CSS设计网页方法是非常重要的,笔者经常使用且经常误使用,所以根据经验和网上资料整理出切合自己的内容,以备 ...

  7. css中margin:0 auto没作用

    很多初学制作网页的朋友,可能会遇到的一个常见问题,就是在CSS中加了margin:0 auto;却没有效果,不能居中的问题!margin:0 auto;的意思就是:上下边界为0,左右根据宽度自适应!其 ...

  8. css中margin为负数的深入研究

    注:以下实验的元素均为块级元素,inline-block和inline本身对margin某些方向上都是无效的,所以这里不予讨论. margin-left或者margin-right为负数 当块元素wi ...

  9. css中margin上下外边距重叠问题

    css的盒子模型里是这样规定两个对象之间的距离的:对象之间的间距是由两个对象的盒子模型的最终计算值得出来的,也就是说两个对象之间的间距就是两个对象的距离,但是当遇到两个对象一个有下外边距margin, ...

随机推荐

  1. Storm官方文档翻译之设置开发环境

    本文将介绍如何设置Storm的开发环境.下面是大纲: 1.下载Storm发布包,解压,将解压的 bin目录放到你电脑的PATH中. 2.为了能够在远程集群中启动或者停止Topology,请将集群信息放 ...

  2. elasticsearch 集群基本概念

    cluster 代表一个集群,集群中有多个节点,其中有一个为主节点,这个主节点是可以通过选举产生的,主从节点是对于集群内部来说的.es的一个概念就是去中心化,字面上理解就是无中心节点,这是对于集群外部 ...

  3. mysql grant授权

    MySQL 赋予用户权限命令的简单格式可概括为: grant 权限 on 数据库对象 to 用户 一.grant 普通数据用户,查询.插入.更新.删除 数据库中所有表数据的权利. grant sele ...

  4. spring xsd

    http://ljhzzyx.blog.163.com/blog/static/3838031220132239471608/ spring配置文件报找不到xsd文件错误 2013-03-23 10: ...

  5. ListView控件的Insert、Edit和Delete功能(第一部分)

    摘自:http://blog.ashchan.com/archive/2007/08/28/listview-control-insert-edit-amp-delete-part-1aspx/ Li ...

  6. JS-日期框、下拉框、全选复选框

    <!-- 下拉框 --><link rel="stylesheet" href="static/ace/css/chosen.css" /&g ...

  7. websphere安装

    下午来再输 websphere 配置库中已存在应用程序,异常处理 出现此问题的原因之一:操作界面上没有卸载完成. 进行一下操作: 1.删除 $WAS_HOME/profiles/AppSrv01/co ...

  8. HDU ACM 1495 非常可乐(广搜BFS)

    非常可乐 Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 32768/32768K (Java/Other) Total Submissi ...

  9. 转:LR的响应时间与使用IE所感受时间不一致的讨论

    在做性能测试时,有时碰到这样一种情况,使用性能工具LR测试出来的响应时间比实际使用IE感受到的时间要长,例如,实际使用IE打开一个系统时只需要1~2秒,而使用LR跑一个用户所得出的结果可能是8秒.10 ...

  10. 在 Linux 系统中安装Load Generator ,并在windows 调用方法

    在 Linux 系统中安装Load Generator ,并在windows 调用 由于公司需要测试系统的最大用户承受能力,所以需要学习使用loadrunner.在安装的时候碰到了不少问题,所以写下此 ...