Skip to content

理解 BFC ( Block Formatting Contexts ) 块级格式化上下文 #3

@shushu2013

Description

@shushu2013

参考

详说 Block Formatting Contexts (块级格式化上下文)

理解 CSS 中 BFC

1、概念

块级格式化上下文 (block formatting context) 是页面上的一个独立的渲染区域,容器里面的子元素不会在布局上影响到外面的元素。

创建一个块级格式化上下文:
1、float 不为 none
2、position 的值为 absolutefixed
3、 display 为以下其中之一的值:inline-blocktable-celltable-captionflexinline-flex
4、overflowvisible 以外的值 (hidden, auto, scroll)

在 CSS3 中,BFC 叫做 Flow Root,并增加了一些触发条件:

display 的值为 table-caption。
position 为 fixed,其实 fixed 是 absolute 的一个子类,因此在 CSS2.1 中使用这个值也会触发 BFC,只是在 CSS3 中更加明确了这一点。

2、BFC 特性

2.1 阻止垂直方向上的外边距叠加

垂直外边距叠加规则

仅当两个块级元素相邻并且在同一个BFC上下文时,它们在垂直方向之间的外边距才会叠加(实际外边距以最大的那个外边距为准)。

<style type="text/css">
    * {
        margin: 0;
        padding: 0;
    }
    .l-wrap {
        margin: 0 auto;
        width: 800px;
        background: green;  
    }
    p {
        margin: 10px 0;
        background: yellow;
    }
</style>

<div class="l-wrap">
    <p>some text 1</p>
    <p>some text 2</p>
    <p>some text 3</p>
</div>

以上三个 p 元素中,中间的 p 元素与相邻的 p 元素在垂直外边距上产生了叠加,因此相邻边距仍为 10px,而不会是 20px。

阻止垂直外边距叠加

当两个块在不同的 BFC 上下文时,垂直外边距不会叠加。

修改上面的例子,使中间的 p 元素属于新的 BFC 上下文,这时垂直相邻边距变为 10px + 10px = 20px

<style type="text/css">
    * {
        margin: 0;
        padding: 0;
    }
    .l-wrap {
        margin: 0 auto;
        width: 800px;
        background: green;  
    }
    .l-bfc {
        overflow: hidden;
    }
    p {
        margin: 10px 0;
        background: yellow;
    }
</style>

<div class="l-wrap">
    <p>some text 1</p>
    <div class="l-bfc">
        <!-- 如果直接设置 p 产生 BFC,
        设置 inline-block、table-caption、inline-flex 有效,其他无效-->
        <p>some text 2</p>
    </div>
    <p>some text 3</p>
</div>

2.2 包含浮动元素

清除浮动时,有一种方法是设置浮动元素父元素 overflow 属性为 hidden 或 auto 。

这正是利用了 overflow: hidden/auto 触发浮动元素的父元素的 BFC 特性,来包含浮动元素。

<style type="text/css">
    * {
        margin: 0;
        padding: 0;
    }
    .l-wrap {
        margin: 0 auto;
        width: 800px;
        background: green;
    }
    .l-bfc {
        overflow: hidden;
    }
    .o-col {
        float: left;
        width: 31.33%;
        margin: 0 1%;
        background: blue;
    }
</style>
<div class="l-wrap l-bfc">
    <div class="o-col">col 1</div>
    <div class="o-col">col 2</div>
    <div class="o-col">col 3</div>
</div>

2.3 阻止元素被浮动元素覆盖

例子:

<style type="text/css">
    * {
        margin: 0;
        padding: 0;
    }
    .l-wrap {
        margin: 0 auto;
        width: 800px;
        background: green;
    }
    .l-bfc {
        overflow: hidden;
    }
    .floated {
        float: left;
        height: 80px;
        background: red;
        color: white;
        opacity: .6;
    }
    p {
        background: black;
        color: white;
    }
</style>

<div class="l-wrap l-bfc"> 
    <div class="floated">Floated div</div> 
    <p class="l-bfc" style="width: 800px">
        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 不再需要移位,文字最终将会环绕在浮动元素的下方。

给 p 元素创建一个新的 BFC,那么 p 就不会被浮动元素覆盖

<div class="l-wrap l-bfc"> 
    <div class="floated">Floated div</div> 
    <p class="l-bfc" style="width: 800px">
        Quae hic ut ab perferendis sit quod architecto,dolor debitis quam rem provident aspernatur tempora expedita.
    </p>  
</div>

如果父元素宽度不足于容纳 浮动元素和 p 元素,p元素会自动下沉到下一行显示。

<div class="l-wrap l-bfc"> 
    <div class="floated">Floated div</div> 
    <p class="l-bfc" style="width: 800px">
        Quae hic ut ab perferendis sit quod architecto,dolor debitis quam rem provident aspernatur tempora expedita.
    </p> 
</div>

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions