`
天梯梦
  • 浏览: 13733551 次
  • 性别: Icon_minigender_2
  • 来自: 洛杉矶
社区版块
存档分类
最新评论

CSS: 深入理解BFC和Margin Collapse (margin叠加或者合并外边距)

阅读更多

BFC的理解与应用

首先我们来看看w3c规范对BFC的解释,其实对于这种概念的学习上,我们总是建议首先寻找官方的定义,因为原则上来说官方的才是最权威和正确的,而且还比较详细,千万不要因为看到英文就畏惧不前。

 

什么是BFC(Block formatting contexts)

w3c规范中的BFC定义

浮动元素和绝对定位元素,非块级盒子的块级容器(例如 inline-blocks, table-cells, 和 table-captions),以及overflow值不为“visiable”的块级盒子,都会为他们的内容创建新的BFC(块级格式上下文)。

在BFC中,盒子从顶端开始垂直地一个接一个地排列,两个盒子之间的垂直的间隙是由他们的margin 值所决定的。在一个BFC中,两个相邻的块级盒子的垂直外边距会产生折叠。

在BFC中,每一个盒子的左外边缘(margin-left)会触碰到容器的左边缘(border-left)(对于从右到左的格式来说,则触碰到右边缘)。

 

BFC的通俗理解:

首 先BFC是一个名词,是一个独立的布局环境,我们可以理解为一个箱子(实际上是看不见摸不着的),箱子里面物品的摆放是不受外界的影响的。转换为 BFC的理解则是:BFC中的元素的布局是不受外界的影响(我们往往利用这个特性来消除浮动元素对其非浮动的兄弟元素和其子元素带来的影响。)并且在一个 BFC中,块盒与行盒(行盒由一行中所有的内联元素所组成)都会垂直的沿着其父元素的边框排列。

 

BFC的运用

在w3c的规范中,除了上面的一段定义之外,BFC的相关知识点分布地比较零散,但基本集中在float、绝对定位、margin collaspe中。下面我们来看看如何应用到BFC来解决问题。

在很多网站中,我们经常会看到这样的一种,左边图片+右边信息的两栏结构,下面我们来看看如何利用BFC来实现。

 

首先我们给出这样的结构:

<style>
.box {width:210px;border: 1px solid #000;float: left;}
.img {width: 100px;height: 100px;background: #696;float: left;}
.info {background: #ccc;color: #fff;}
</style>

<div class="box">
    <div class="img">image</div>
    <p class="info">信息信息信息信息信息信息信息信息信息信息信息信</p>
</div>

 

一般情况下它呈现出我们所乐意看到的样子:

CSS: 深入理解BFC和Margin Collapse (margin叠加或者合并外边距)

但随着文字信息增多后,会变地非常的糟糕:

CSS: 深入理解BFC和Margin Collapse (margin叠加或者合并外边距)

很 明显,这是因为info类里面的文字受到了浮动元素的影响,但这并不是我们所期望的。此时我们可以为P元素的内容建立一个BFC,让其内容消除对 外界浮动元素的影响。根据上文所知,只要给info元素添加overflow:hidden;即可为其内容建立新的BFC。当然你也可以通过其他方法来建 立。其效果如下:

CSS: 深入理解BFC和Margin Collapse (margin叠加或者合并外边距)

合并外边距与BFC(或者 margin叠加)

在CSS当中,相邻的两个盒子(可能是兄弟关系也可能是祖先关系)的外边距可以结合成一个单独的外边距。这种合并外边距的方式被称为折叠,并且因而所结合成的外边距称为折叠外边距。

 

折叠的结果:

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

产生折叠的必备条件:margin必须是邻接的!

而根据w3c规范,两个margin是邻接的必须满足以下条件:

  • 必须是处于常规文档流(非float和绝对定位)的块级盒子,并且处于同一个BFC当中。
  • 没有线盒,没有空隙(clearance,下面会讲到),没有padding和border将他们分隔开
  • 都属于垂直方向上相邻的外边距,可以是下面任意一种情况
    • 元素的margin-top与其第一个常规文档流的子元素的margin-top
    • 元素的margin-bottom与其下一个常规文档流的兄弟元素的margin-top
    • height为auto的元素的margin-bottom与其最后一个常规文档流的子元素的margin-bottom
    • 高度为0并且最小高度也为0,不包含常规文档流的子元素,并且自身没有建立新的BFC的元素的margin-top和margin-bottom

以上的条件意味着下列的规则:

  • 创建了新的BFC的元素(例如浮动元素或者'overflow'值为'visible'以外的元素)与它的子元素的外边距不会折叠
  • 浮动元素不与任何元素的外边距产生折叠(包括其父元素和子元素)
  • 绝对定位元素不与任何元素的外边距产生折叠
  • inline-block元素不与任何元素的外边距产生折叠
  • 一个常规文档流元素的margin-bottom与它下一个常规文档流的兄弟元素的margin-top会产生折叠,除非它们之间存在间隙(clearance)。
  • 一个常规文档流元素的margin-top 与其第一个常规文档流的子元素的margin-top产生折叠,条件为父元素不包含 padding 和 border ,子元素不包含 clearance。
  • 一 个 'height' 为 'auto' 并且 'min-height' 为 '0'的常规文档流元素的 margin-bottom 会与其最后一个常规文档流子元素的 margin-bottom 折叠,条件为父元素不包含 padding 和 border ,子元素的 margin-bottom 不与包含 clearance 的 margin-top 折叠。
  • 一个不包含border-top、 border-bottom、padding-top、padding-bottom的常规文档流元素,并且其 'height' 为 0 或 'auto', 'min-height' 为 '0',其里面也不包含行盒(line box),其自身的 margin-top 和 margin-bottom 会折叠。

(下面我们对不产生折叠的情况逐一分析。)

浮动和绝对定位不与任何元素产生 margin 折叠

原因:浮动元素和绝对定位元素不与其他盒子产生外边距折叠是因为元素会脱离当前的文档流,违反了上面所述的两个margin是邻接的条件同时,又因为浮动和绝对定位会使元素为它的内容创建新的BFC,因此该元素和子元素所处的BFC是不相同的,因此也不会产生margin的折叠。

 

DEMO:

<style>
body {padding:0;margin: 0; text-align: center;}
.wrapper {margin:30px;width: 450px;border:1px solid red;}
.small-box {width: 50px;height: 50px;margin: 10px;background: #9cc;}
.middle-box {width: 100px;height: 100px;margin: 20px;background: #99c;}
.big-box {width: 120px;height: 120px;margin: 20px;background: #33e;}
.floatL {float: left;}
.floatR {float: right;}
.clear {clear: both;}
.posA {position: absolute;}
.overHid{overflow: hidden;}
.red {background: #f00;}
.green {background: #0f0;}
.blue {background: #00f;}
</style>

<div class="wrapper overHid">
    <div class="big-box blue">non-float</div>
    <div class="middle-box green floatL">
        <div class="small-box red"></div>
        float left
    </div>
</div>

 

CSS: 深入理解BFC和Margin Collapse (margin叠加或者合并外边距)

但是浮动元素脱离了当前的BFC并不影响它后面的兄弟元素,后面的兄弟元素与浮动元素前面的元素依然在同一个BFC当中,所以,它们之间的margin还是会折叠的。下面我们对上面的demo做一下修改:

<div class="wrapper overHid">
    <div class="big-box">non-float</div>
    <div class="middle-box green floatL">float left</div>
    <div class="middle-box red">non-clear</div>
</div>

 

CSS: 深入理解BFC和Margin Collapse (margin叠加或者合并外边距)

从上面这个修改后的demo中可以看出,红色的块盒在没有清楚浮动的情况下,它的margin-top和蓝色块盒的margin-bottom产生了折叠,这证明了我上面的结论。

 

下面我们来谈谈 'clearance' 这个神奇的东西,当浮动元素之后的元素设置clear以闭合相关方向的浮动时,根据w3c规范规定,闭合浮动的元素会在其margin-top以上产生一 定的空隙(clearance,如下图),该空隙会阻止元素margin-top的折叠,并作为间距存在于元素的margin-top的上方。关于这个间 距的计算稍微有点复杂,但实际工作中你并不需要去计算它,我们先来看看例子吧:

<div class="wrapper overHid">
    <div class="big-box" style="box-shadow:0 20px 0 rgba(0,0,255,0.2);">non-float</div>
    <div class="middle-box green floatL" style="opacity:0.6">float left</div>
    <div class="middle-box red clear" style="margin-top:40px;box-shadow:0 -40px 0 rgba(255,0,0,0.2);">clear</div>
</div>

 

CSS: 深入理解BFC和Margin Collapse (margin叠加或者合并外边距)

上 面的图中我们可以看到,我们为红色块盒设置的40px的margin-top(这里我们通过相同高度的阴影来将其可视化)好像并没有对紫色块盒起 作用,而且无论我们怎么修改这个margin-top值都不会影响红色块盒的位置,而只由绿色块盒的margin-bottom所决定。

 

也就是说,我们只需要知道,闭合浮动的元素的border-top会紧贴着相应的浮动元素的margin-bottom。

原 来,通过w3c的官方规范可知,闭合浮动的块盒在margin-top上所产生的间距(clearance)的值与该块盒的margin-top 之和应该足够让该块盒垂直的跨越浮动元素的margin-bottom,使闭合浮动的块盒的border-top恰好与浮动元素的块盒的margin- bottom相邻接。

 

用上图例子中的相关值可以得出这样一个式子:r-margin-top + r-clearance = g-margin-top + g-height + g-margin-bottom

PS!闭合浮动并不能使浮动元素回到原来的BFC当中!

 

分析二:inline-block元素与其兄弟元素、子元素和父元素的外边距都不会折叠(包括其父元素和子元素)

inline-block不符合w3c规范所说元素必须是块级盒子的条件,因为规范中又说明,块级盒子的display属性必须是以下三种之一:'block', 'list-item', 和 'table'。

 

参考资料

出处:http://www.w3cplus.com/css/understanding-bfc-and-margin-collapse.html

 

总结margin的重叠(或合并外边距)

就参照标准的文档,结合自己的理解稍微翻译了一下,有些名词还是用英文描述比较合适。文档地址:点这里

在CSS中,两个或者更多的盒子的毗邻的外边距会重叠在一起,形成一个单一的外边距。外边距的这种组合方式我们称之为“坍塌”,最后形成的外边距我们称之为“坍塌的外边距(collapse margin)”。

垂直方向上的外边距的坍塌,除了:

  1. 根元素的盒子(the root elements’s box)的外边距永远不会坍塌。当你为 html 标签加上 margin 时,无论有无毗邻的外边距,这个margin的都不会坍塌,是多少就多少。
  2. 如果一个拥有了“空隙”(clearance)的元素上下外边距毗邻,它的外边距将会与后面的兄弟元素的相邻外边距发生坍塌,但是发生坍塌后形成的外边距不会与父盒子的底外边

水平方向的外边距永远不会坍塌。

什么情况下两个外边距才算是毗邻(adjoining)呢?有且只有在下面的情况中:

  1. 同一个块级格式化上下文(block formatting context)中未脱离正常流(in-flow)中的块级盒子的外边距;
  2. 两个外边距之间不存在 line box(不包括高度确定无疑为零的 line box),没有 clearance,外边距和边框;
  3. 垂直相邻的的盒子之间的外边距,可以下面的任一种情况:
    元素的 margin-top 与其第一个正常流(in-flow)的子元素的 margin-top
    元素的 margin-top 与其第一个正常流的子元素的 margin-top ;
    height为auto的元素的 margin-bottom 与其最后一个正常流的子元素的 margin-bottom ;
    高度为0并且最小高度也为0,不包含正常流的子元素,并且自身没有建立新的BFC的元素的 margin-topmargin-bottom ;

形成坍塌的外边距的元素可以使非相邻元素或者祖先元素。

上面说到的也就意味着:

  • 一个浮动的盒子与其他的盒子不会发生外边距坍塌,即使是浮动盒子和它内部的正常流中的孩子们;
  • 自身建立了新的BFC的元素的外边距不会与它的处于正常流的孩子们的外边距重叠;
  • inline-block 盒子的外边距不会坍塌,即使是它内部的正常流中的孩子们;
  • 一个正常流元素的 margin-bottom 与它下一个正常流的兄弟元素的 margin-top 会产生折叠,除非它们之间存在间隙(clearance)。
  • 一个正常流元素的 margin-top 与其第一个正常流的子元素的 margin-top 产生折叠,条件为父元素不包含 paddingborder ,子元素不包含 clearance。
  • 一个 ‘height’ 为 ‘auto’ 并且 ‘min-height’ 为 ‘0’的正常流元素的 margin-bottom 会与其最后一个正常流子元素的 margin-bottom 折叠,条件为父元素不包含 paddingborder ,子元素的 margin-bottom 不与包含 clearance 的 margin-top 折叠。
  • 一个不包含 border-topborder-bottompadding-toppadding-bottom的正常流元素,并且其 ‘height’ 为 0 或 ‘auto’, ‘min-height’ 为 ‘0’,其里面也不包含行盒(line box),其自身的 margin-topmargin-bottom 会折叠。

 

关联文章:详解CSS的盒模型(box model) 及 CSS3新增盒模型计算方式box-sizing

本文转自:CSS: 深入理解BFC和Margin Collapse (margin叠加或者合并外边距)

 

 

 

 

 

 

 

 

 

分享到:
评论

相关推荐

    理解margin塌陷和margin合并及其解决方案.docx

    在CSS布局中,margin塌陷是指在嵌套元素中,子元素的上外边距(`margin-top`)与父元素的上外边距重合时,它们不会简单地叠加,而是会合并成一个外边距。这种合并会导致子元素相对于父元素的位置不是预期中的那样。...

    HTML-bfc初探

    - **清除浮动**:在BFC内,子元素不会影响其外边距,可以解决父元素因浮动子元素而高度塌陷的问题。 - **防止元素重叠**:BFC区域内的元素不会与BFC区域外的元素发生重叠。 - **内部元素垂直居中**:通过创建BFC...

    如何解决外边距margin叠加的问题探讨

    在CSS布局中,经常会遇到块级元素垂直外边距(margin)发生叠加的问题,这通常称为margin叠加或外边距折叠。当两个或多个毗邻的块级元素垂直方向上的margin相遇时,它们会以较大者的margin值作为一个统一的margin值...

    详解css外边距折叠(margin collapsing)

    CSS中的外边距折叠指的是相邻的两个或多个块级元素的外边距(margin)会合并成一个外边距。这种情况在块级元素垂直排列时尤为常见,比如相邻兄弟元素之间、父元素与第一个或最后一个子元素之间以及空的块级元素之间...

    Web-前端html+css从入门到精通 132. BFC规范(上).zip

    BFC(Block Formatting Context,块级格式化上下文)是CSS布局中的一个重要概念,对于理解和解决网页布局问题有着至关重要的作用。本篇将深入探讨BFC规范,帮助初学者从入门到精通。 BFC全称为Block Formatting ...

    10分钟理解CSS BFC原理及其应用

    1. **外边距折叠(Margin Collapsing)**:在同一个BFC中,相邻的垂直外边距会合并。例如,两个在同一BFC下的div元素,它们之间的外边距只会显示为两者中较大的那个。要避免这种情况,可以将它们置于不同的BFC中,如...

    BFC的布局规则.docx

    同一BFC内的相邻块级元素,其顶部和底部外边距(margin)会相互重叠,而不是简单相加。例如,一个div的下外边距为20px,另一个div的上外边距为40px,实际效果中两个div之间的间距将是40px,而不是60px。 3. **...

    bfc的详细介绍以及大总结

    5. **边界重叠**:在BFC内部,元素的垂直外边距(margin)可能会发生重叠,但是这种重叠仅限于同一个BFC内部的元素之间。 6. **布局独立性**:BFC内部的元素布局不会影响到外部元素,同时也不会受到外部元素的影响。...

    诱发BFC的原因及处理方案

    总结来说,理解并掌握BFC的概念对于优化CSS布局、解决浮动元素带来的问题以及避免外边距折叠等现象至关重要。通过合理利用BFC,开发者可以更好地控制网页元素的排列和显示,提升用户体验。在实际项目中,熟练运用...

    Web-前端html+css从入门到精通 133. BFC规范(下).zip

    3. **内外边距重叠**:在BFC内部,垂直方向上的相邻元素的外边距会发生重叠,这是BFC的一个特性,而在不同BFC之间则不会出现这种情况。 4. **隔离作用域**:BFC能够隔离内外边距、浮动元素的影响,使得元素之间的...

    前端大厂最新面试题-BFC.docx

    在前端开发中,BFC(Block Formatting Context,块级格式化上下文)是一个非常重要的概念,它关乎到网页布局和元素间的相互影响。面试中,理解并能灵活...因此,对于前端工程师来说,深入理解和运用BFC是非常必要的。

    clear:both后margin-top不起作用其他左右下都起作用

    在BFC中,元素的顶部外边距不会与其包含块或者浮动元素的底部外边距发生合并,这就是为什么`margin-top`看起来没有影响到第二个`div`的垂直位置。相反,`margin-bottom`和`margin-right`依然按照常规方式起作用,...

    前端基础——文档流与BFC

    1. 防止外边距重叠:在BFC中,相邻的块级元素的外边距不会相互合并,而是各自独立。 2. 计算高度:BFC内部元素的高度不会影响外部元素,BFC会根据其内部元素自动计算自身的高度,除非设置明确的高度。 3. 布局隔离:...

    2023前端最新面试题之CSS-127页

    1. 盒模型(Box Model):在CSS中,每个元素都可以看作是一个矩形的盒子,它包括内容区域(content)、内边距(padding)、边框(border)和外边距(margin)。盒模型的 width 和 height 是指内容区域的宽度和高度,...

    CSS+DIV网页布局技巧(精髓)

    在IE中,两个相邻的块级元素可能会出现外边距折叠现象,即两个元素之间的外边距会被合并成一个较大的值。为了避免这种情况,可以在两个元素之间插入一个空的 `div`,并为其设置 `clear: both;`。 ```css .clear { ...

    CSS 清除浮动与BFC的方法

    BFC:块级格式化上下文 BFC的布局规则 内部的Box会在垂直方向,一个接一个地放置。 Box垂直方向的距离由margin决定。属于同一个BFC的两个相邻Box的margin会发生重叠。 计算BFC的高度时,浮动元素也参与计算。 ...

    如何理解 CSS 布局和块级格式上下文

    CSS布局和块级格式上下文(Block Formatting Context,简称BFC)是理解CSS布局机制的关键概念。BFC是一个独立的布局环境,它有自己的渲染规则,能够决定内部元素如何排列以及与外部元素如何交互。在CSS中,BFC主要...

    CSS理解块级格式上下文(BFC)

    1.BFC 定义 BFC(Block formatting context)直译为"块级格式化上下文"。它是一个独立的渲染区域,只有Block-level box(块级元素)参与, 它规定了内部的Block-level Box如何布局,并且与这个区域外部毫不相干. 通俗...

    浅谈CSS潜藏着的BFC

    2. 属于同一个BFC的元素的垂直外边距可能会发生重叠(margin collapse)。这是因为它们的垂直距离由margin决定。 3. BFC中的子元素的左外边距会与包含块的左边界相接触,即便存在浮动元素也一样。 4. BFC区域不会与...

    常见的一些面试题和一些css技巧,就是、技巧.zip

    "常见的一些面试题和一些css技巧,就是、技巧.zip"这个压缩包文件显然包含了与面试准备和CSS技术相关的材料,特别是对于那些希望提升自己的前端开发者或者求职者来说,这是一个宝贵的学习资源。以下是一些可能涵盖的...

Global site tag (gtag.js) - Google Analytics