Bootstrap

BFC概念和清除浮动

一、BFC概念

BFC 即 Block Formatting Contexts (块级格式化上下文),是W3C CSS2.1规范中的一个概念,决定了元素如何对其内容进行定位,以及与其他元素的关系和相互作用。具有BFC特性的元素可以看做是隔离了的独立容器,容器里面的元素不会在布局上影响到外面的元素,并且BFC具有普通容器所没有的的一些特性

二、BFC生成条件

只要元素满足下面任一条件即可触发BFC特性:

  • body 根元素
  • 浮动元素:float 除 none 以外的值
  • 绝对定位元素:position (absolute、fixed)
  • display 为 inline-block、table-cells、flex
  • overflow 除了 visible 以外的值(hidden、auto、scroll)

三、BFC的约束规则

BFC的约束规则

浏览器对于BFC这块区域的约束规则如下:

  • 生成BFC元素的子元素会一个接一个的放置。垂直方向上他们的起点是一个包含块的顶部,俩个相邻子元素之间垂直距离取决于元素margin特性。在BFC中相邻的块级元素外边距会折叠。
  • 生成BFC元素的子元素中,每一个子元素的外边距和包含块的左边界相接触,(对于从右到左的格式化,右外边距和右边界相接触),除非这个子元素也创建了一个新的BFC(如它自身也是一个浮动元素)。
有朋友对它做了分解,我们直接拿来:
  • 内部的BOX会在垂直方向上一个接一个的放置;
  • 垂直方向上的距离有margin决定。(完整的说法是:属于同一个BFC的俩个相邻的BOX的margin会发生重叠,与方向无关。)
  • 每个元素的左外边距与包含块的左边界相接触(从左到右),即使浮动元素也是如此。(这说明BFC中的子元素不会超出它的包含块,而position为absolute的元素可以超出它的包含块边界);
  • BFC的区域不会与float的元素区域重叠;
  • 计算BFC的高度时,浮动子元素也参与计算;
  • BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素,反之亦然;
CSS的几条规则:
  • Block元素会扩展到与父元素同宽,所以block元素会垂直排列;
  • 垂直方向上的俩个相邻DIV的margin会重叠,而水平方向不会(此规则并不完全正确);
  • 浮动元素会尽量往左上方(或右下方);
  • 为父元素设置overflow:hidden或浮动父元素,则会包含浮动元素;

BFC应用场景

1.防止margin重叠
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style type="text/css">
        .box{
            overflow: hidden;//触发BFC
        }
        .box p{
            width: 100px;
            height: 100px;
            background-color: antiquewhite;
            margin: 20px;
        }
    </style>
</head>
<body>
<div class="box">
    <p></p>
</div>
<div class="box">
    <p></p>
</div>
</body>
</html>

如果想要避免外边距的重叠,可以将其放在不同的 BFC 容器中。
如下图,margin不重叠
在这里插入图片描述

2.浮动相关问题

高度塌陷问题,在通常情况下父元素的高度会被子元素撑开,而在这里因为其子元素为浮动元素所以父元素发生了高度坍塌,上下边界重合,这时就可以用BFC来清除浮动了。

<div style="border: 1px solid #000;">
    <div style="width: 100px;height: 100px;background: grey;float: left;"></div>
</div>

在这里插入图片描述
由于容器内元素浮动,脱离了文档流,所以容器只剩下2px的边距高度。如果触发容器的BFC,那么容器将会包裹浮动元素。

<div style="border: 1px solid #000;overflow: hidden">
    <div style="width: 100px;height: 100px;background: grey;float: left;"></div>
</div>

在这里插入图片描述

3.阻止元素被浮动元素覆盖

div浮动兄弟这该问题:由于左侧块级元素发生了浮动,所以和右侧未发生浮动的块级元素不在同一层内,所以会发生div遮挡问题。可以给右侧元素添加 overflow: hidden,触发BFC来解决遮挡问题。

<div style="height: 100px;width: 100px;float: left;background: lightblue">我是一个左浮动的元素</div>
<div style="width: 200px; height: 200px;background: grey">我是一个没有设置浮动, 
也没有触发 BFC 元素, width: 200px; height:200px; background: grey;</div>

在这里插入图片描述
这时候其实第二个元素有部分被浮动元素所覆盖,但是文本信息不会被浮动元素所覆盖,如果想避免元素被覆盖,可触发第二个元素的BFC特性,在第二个元素中加入overflow:hidden,就会变成:

<div style="height: 100px;width: 100px;float: left;background: lightblue">我是一个左浮动的元素</div>
<div style="width: 200px; height: 200px;background: grey;overflow:hidden">我是一个没有设置浮动, 
也没有触发 BFC 元素, width: 200px; height:200px; background: grey;</div>

在这里插入图片描述

这个方法可以用来实现两列自适应布局,效果不错,这时候左边的宽度固定,右边的内容自适应宽度。

清除浮动

1、尾部添加div

<div>
    <p style="float:left">
    </p>
    <div style="clear:both"></div>
</div>

这个方法通俗点将就是,父元素下面的子元素都浮动了,如果有一个不浮动岂不是就能包住了?没错这个方法就是尾部添加div的方式思想。
2、伪类清除

<style>
    .clearfix{
        *zoom:1;
    }
    .clearfix:after{
        content:"";
        display:block;
        clear:both;
    }
</style>
<div class="clearfix">
    <ul style="float:left">
        <li>1</li>
        <li>2</li>
        <li>3</li>
    </ul>
</div>

3、BFC处理
也就是触发BFC的生成条件
3.1、设置父元素float的值不为none

<div style="float:left">
    <ul style="float:left">
        <li>1</li>
        <li>2</li>
        <li>3</li>
    </ul>
</div>

3.2、设置父元素overflow的值不为visible

<div style="overflow:hidden">
    <ul style="float:left">
        <li>1</li>
        <li>2</li>
        <li>3</li>
    </ul>
</div>

3.3、display的值为inline-block、table-cell、table-caption

<div style="display:inline-block">
    <ul style="float:left">
        <li>1</li>
        <li>2</li>
        <li>3</li>
    </ul>
</div>

用这个方法时注意ie8不支持inline-block

3.4、position的值为absolute或fixed

<div style="position:fixed">
    <ul style="float:left">
        <li>1</li>
        <li>2</li>
        <li>3</li>
    </ul>
</div>

参考:
我对BFC的理解
浅析BFC原理及作用
BFC与清除浮动

;