04-BFC 和 Margin Collapse

1. BFC

BFC(Block Formatting Context)直译为“块级格式化范围”。
是 W3C CSS 2.1 规范中的一个概念,它决定了元素如何对其内容进行定位,以及与其他元素的关系和相互作用。
当涉及到可视化布局的时候,Block Formatting Context提供了一个环境,HTML元素在这个环境中按照一定规则进行布局。一个环境中的元素不会影响到其它环境中的布局。
比如浮动元素会形成BFC,浮动元素内部子元素的主要受该浮动元素影响,两个浮动元素之间是互不影响的。这里有点类似一个BFC就是一个独立的行政单位的意思。

也可以说BFC就是一个作用范围。可以把它理解成是一个独立的容器,并且这个容器的里box的布局,与这个容器外的毫不相干

  • BFC中,盒子从包含块的顶部一个个在垂直方向上排列。
  • 两个兄弟元素的垂直距离由margin决定。同一个BFC中的块级兄弟元素的垂直外边距会被叠加。
  • 在BFC中,每个盒子的左外边距接触包含块的左边(从右到左的也一样),即使存在浮动元素也一样(即使盒子的行内盒子会由于浮动和紧缩,即这个盒子会由于浮动而变窄)。

解决方法:
1. 用overflow解决外边距叠加
示例:

<div class="container">
             <p>Sibling 1</p>
             <p>Sibling 2</p>
             <p>Sibling 3</p>
<div>

<style>
.container {            
    width: 500px;
    border: 1px solid green; 
    overflow: hidden;
 } 

p { margin: 10px 0; 
     background-color: lightgreen; 
} 

.newBFC { 
     overflow: hidden;
}
 <style/>                   

效果:
这里写图片描述

  • 从示例中我们可以看出,盒子都是从包含块的顶部开始一个接着一个垂直堆放的。

    • box1 和 box2 垂直堆放, 他们里边的子元素也相互垂直堆放
  • 子盒子1和子盒子2垂直外边距应该是20px+20px,但是并未相加,这就是垂直外边距合并

  • box1浮动后不占位置, box2就跑到box1下面看不见了,但是给 box2的最后一个子元素设置 overflow: hidden 就可以显现出来

这是因为 overflow: hidden 触发了元素的 BFC ,
BFC 的特性:元素自成一个独立的盒子,从顶部按垂直方向堆放 ,垂直方向的外边距被合并了
因此就变成上图的样式了

使用 BFC 防止垂直外边距折叠
看到这里你可能有些困惑,因为在前面我们讨论了正是由于 BFC 导致外边距折叠的问题。
但是 BFC 垂直外边距折叠的问题只有当元素在同一个 BFC 时才会发生
如果不属于同一个 BFC,他们之间的外边距将不会折叠。所以通过创建一个新的BFC我们可以防止外边距折叠。

 <div class="container">
             <p>Sibling 1</p>
             <p>Sibling 2</p>             
             <div class="newBFC"> 
                    <p>Sibling 3</p>
            </div> 
        </div>

.container {            
     width: 500px;
     border: 1px solid green; 
     overflow: hidden;
} 

 p { margin: 10px 0; 
     background-color: lightgreen; 
} 
  .newBFC { 
       overflow: hidden;
 }

效果:
这里写图片描述

让需要外边距可以正常显示的元素和其他元素分属于不同的 BFC 就可以解决外边距折叠这个问题

使用BFC来包含浮动

一个BFC可以包含浮动。很多时候我们会碰到这种情况,一个容器里有浮动元素。由于这个原因,容器元素没有高度,它的浮动孩子将会脱离页面的常规流。我们通常使用清除浮动来解决这个问题,最受欢迎的方法是使用一个 clearfix 的伪类元素。但我们同样可以通过定义一个 BFC 来达到这个目的。

示例:

<div class="container">
    <div>Sibling</div> 
    <div>Sibling</div> 
</div>

.container { 

    background-color: green;
    overflow: hidden;
 }
 .container div {
     float: left; 
     background-color: lightgreen;
    margin: 10px; 
    }

在上面的这个案例中,如果不给父容器添加overflow: hidden,父容器将不会有任何的高度,它将不会包含已经浮动的子元素。
为了解决这个问题,我们通过添加 overflow: hidden,在容器中创建一个新的 BFC。
现在,这个容器将包含浮动的子元素,它的高度将扩展到可以包含它的子元素,在这个BFC,这些元素将会回到页面的常规文档流。

3. 使用BFC来防止文字环绕
有时候一个浮动div周围的文字环绕着它(如下图中的左图所示)但是在某些案例中这并不是可取的,我们想要的是外观跟下图中的右图一样的。
为了解决这个问题,我们可能使用外边距,但是我们也可以使用一个BFC来解决。
这里写图片描述

首先让我们理解文字为什么会环绕。为此我们需要知道当一个元素浮动时盒子模型是如何工作的。这就是我之前在讨论BFC对齐时留下的那部分。让我们从下图来了解发生了什么。著作权归作者所有。
这里写图片描述
图中的HTML可以假定为这样:

<div class="container"> 
            <div class="floated">Floated div</div> 
            <p>Quae hic ut ab perferendis sit quod architecto,dolor 
                debitis quam rem provident aspernatur tempora expedita.
            </p> 
  </div>

在上图中的整个黑色区域为p元素。正如我们所看到的,这个p元素并没有移动,但是它却出现在浮动元素的下方。p元素的line boxes(指的是文本行)进行了移位。此处line boxes的水平收缩为浮动元素提供了空间。

随着文字的增加,因为line boxes不再需要移位,最终将会环绕在浮动元素的下方,因此出现了那样的情况。这就解释了为什么即使在浮动元素存在时,段落也将紧贴在包含块的左边框上,还有为什么line boxes会缩小以容纳浮动元素。

如果我们能够移动整个p元素,那么这个环绕的问题就可以解决了。著作权归作者所有。
在去解决之前,让我们再回忆一下W3C标准上是怎么描述的:

在BFC中,每个盒子的左外边框紧挨着左边框的包含块(从右到左的格式化时,则为右边框紧挨)。即使在浮动里也是这样的(尽管一个盒子的边框会因为浮动而萎缩),除非这个盒子的内部创建了一个新的BFC(这种情况下,由于浮动,盒子本身将会变得更窄)

根据这些,如果这个p元素创建了一个新的BFC,那么它将不会紧挨着容器块的左边缘。这个可以通过简单的给p元素添加overflow: hidden来实现。这个方法创建了一个新的BFC解决了文字环绕在浮动元素周围的问题。

4. 在多列布局中使用BFC

如果我们正在创建的一个多列布局占满了整个容器的宽度,在某些浏览器中最后一列有时候将会被挤到下一行。会发生这样可能是因为浏览器舍入(取整)了列的宽度使得总和的宽度超过了容器的宽度。
然而,如果我们在一个列的布局中建立了一个新的BFC,它将会在前一列填充完之后的后面占据所剩余的空间。

<div class="container"> 
            <div class="column">column 1</div>
            <div class="column">column 2</div> 
            <div class="column">column 3</div> 
</div>


.column {
     width: 31.33%; 
     background-color: green; 
     float: left; margin: 0 1%; 
    } 
.column:last-child { 
    float: none; 
    overflow: hidden; 
}

现在即使容器的宽度会有轻微的变化,但是布局也不会中断。当然,这并不是多列布局的最好选择,但它是防止最后一列下滑问题的一种方法。Flexbox在这种情况下可能是一个更好的解决方案,但是这应该要说明一下在这些情况下元素是如何表现的。

触发BFC的条件:
float的属性不是none;
overflow的属性不是visible;
position的属性是absolute,fixed;
display的属性是:inline-block,table-cells,table-caption.
BFC的布局特性:
内部盒子在垂直方向一个接一个放置。
兄弟元素的外边距由margin决定,在同一个BFC里的垂直边距会叠加。(解决办法:创建一个新的BFC)
BFC的高度包含浮动元素。(可用以消除浮动)
BFC的区域不会与浮动盒子重叠。(解决图片环绕效果)
BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值