1

bfc初探

什么是bfc

bfc全称是块级格式化上下文(block formating context),是web可视化css渲染的一部分,它是块级盒子的布局发生,浮动互相交互的部分。

我所理解的bfc本质上是一个透明的箱子,我们完全看不到这个箱子,但是这个箱子是独立于外部其他容器而存在的,在这个箱子内部有bfc内部自己的渲染逻辑。

bfc布局规则

  • bfc内的元素一次从上往下排列。

  • bfc垂直方向的距离有margin决定,且相邻两个元素宽度会发生折叠

  • bfc内部的元素的左边框总是与容器的左边框重合,浮动也不例外

  • bfc不会与float box重叠

  • 计算bfc的高度,浮动也会计算在内

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

触发bfc的条件

  • 根元素或者包含根源的元素

  • float不为none

  • dispaly为absolute或者fixed

  • overflow不为visiable

  • dispaly为inline-block或者table-cell或者table-caption

bfc的应用场景

用bfc包含浮动

如果不创建bfc。浮动元素的父元素的高度会是0,给父元素加一个overflow:hidden。可以把父元素设置成bfc,这样可以使这个元素包含其浮动子元素。

float

//html
<div class="floatdiv1">
    <p>p1</p>
    <p>p2</p>
</div>

<div class="floatdiv2">
    <p>p3</p>
    <p>p4</p>
</div>


//css
.floatdiv1{
    width: 200px;
    overflow: hidden;
    background-color: green;
    border: 1px solid red;
    margin-bottom: 40px;
}
.floatdiv2{
    width: 200px;
    background-color: yellow;
    border: 1px solid blue;
    margin-bottom: 40px;
}
.floatdiv1 p , .floatdiv2 p{
    float: left;
    width: 50px;
    background-color: pink;
    height: 50px;
    margin: 10px;
}

计算bfc的高度的时候,浮动元素也会参与计算。而浮动元素本身是脱离文档流的,非bfc元素的高度计算是不会把浮动元素计算在内。

用bfc阻止文字环绕。

正常情况下,如果一个块级元素设置成了float,那么他的兄弟元素会环绕其布局。

float

//html
<div class="outer">
    <div class="inner1"></div>
    <div class="inner2"></div>
</div>

//css
.outer{
    width: 200px;
}
.inner1{
    float: left;
    height: 50px;
    width: 50px;
    background-color: orange;
}
.inner2{
    background-color: cadetblue;
    height: 200px;
    //overflow: hidden;   这里设置overflow的话就会让inner成为一个bfc
}

如果inner2设置了overflow属性,看到效果是下面的图
img

inner会环绕在浮动元素div周围,因为同一个bfc中,元素左边总是触碰到容器的左边,即使存在浮动也是如此。如果不想这样,可以给文字一个overflow:hidden。这样文字所在的区域就成了一个bfc,bfc是不会和float元素重叠的。

解决外边距折叠问题

外边距折叠的情况:
img
防止外边距折叠的问题的方法是给bfc内部再写一个bfc。

//外边距折叠的情况
//html
<div class="div1">
    <p></p>
    <p></p>
    <p></p>
</div>

//css
.div1{
    width: 200px;
    background-color: blue;
}
.div1 p{
    height: 50px;
    margin: 10px 0;
    background-color: orange;
}

解决方案是,把p标签单独写进一个个的bfc里面,比如在p外边包一层overflow是hidden的div。这样的话,两个p标签不属于一个bfc,就不会发生margin折叠的情况。
img

//html
<div class="div1">
    <p></p>
    <p></p>
    <div class="div2">
        <p></p>
    </div>
</div>

//css
.div1{
    width: 200px;
    background-color: blue;
}
p{
    height: 50px;
    margin: 10px 0;
    background-color: orange;
    overflow: hidden;
}
.div2{
    overflow: hidden;
}

//把第三个p标签写进一个bfc中,这样的话,第二个p和第三个p就不会发生折叠,行距是双倍的行距而不是单倍的。

外边距的执行结果
  • 如果上下的外边距都是正的,间隔距离取外边距的最大值

  • 如果上下的外边距都是负的,间隔距离取外边距绝对值大的

  • 如果上下的外边距一正一副,间隔距离是相加的和

触发外边距折叠的必要条件
  • 元素必须是块级盒子,block,list-item table

  • 元素必须是常规文档流,且处在同一个bfc中

  • 必须是垂直方向上相邻的元素,这两个是触发折叠的必要条件

不会触发折叠的情况
  • 不处在一个bfc中不会触发bfc

  • 另外,浮动元素,position是absolute或者fixed的元素不会出现这种情况,因为不是常规文档流

  • 如果一个父元素含有padding或border,那么他与其第一个子元素不会发生折叠


张小草1018
285 声望8 粉丝