avatar

BFC

什么是BFC?

BFC就是“块级格式化上下文”的意思,创建了 BFC的元素就是一个独立的盒子,不过只有Block-level box可以参与创建BFC, 它规定了内部的 Block-level Box如何布局,并且与这个独立盒子里的布局不受外部影响,当然它也不会影响到外面的元素。

在解释什么是BFC之前,我们需要先知道Box、Formatting Context的概念。

Box:css布局的基本单位

Box 是 CSS 布局的对象和基本单位, 直观点来说,就是一个页面是由很多个 Box 组成的。元素的类型和 display 属性,决定了这个 Box 的类型。 不同类型的 Box, 会参与不同的 Formatting Context(一个决定如何渲染文档的容器),因此Box内的元素会以不同的方式渲染。让我们看看有哪些盒子:

  • block-level box:display 属性为 block, list-item, table 的元素,会生成 block-level box。并且参与 block fomatting context;

  • inline-level box:display 属性为 inline, inline-block, inline-table 的元素,会生成 inline-level box。并且参与 inline formatting context;

    Formatting Context

    Formatting context 是 W3C CSS2.1 规范中的一个概念。它是页面中的一块渲染区域,并且有一套渲染规则,它决定了其子元素将如何定位,以及和其他元素的关系和相互作用。最常见的 Formatting context 有 Block fomatting context (简称BFC)和 Inline formatting context (简称IFC)。

    BFC是一个独立的布局环境,其中的元素布局是不受外界的影响,并且在一个BFC中,块盒与行盒(行盒由一行中所有的内联元素所组成)都会垂直的沿着其父元素的边框排列。

    BFC有一下特性:

    • 内部的Box会在垂直方向,从顶部开始一个接一个地放置。
    • Box垂直方向的距离由margin决定。属于同一个BFC的两个相邻Box的margin会发生叠加
    • 每个元素的margin box的左边, 与包含块border box的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此。
    • BFC的区域不会与float box叠加。
    • BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素,反之亦然。
    • 计算BFC的高度时,浮动元素也参与计算。

    如何创建BFC

    • float 除了none以外的值
    • overflow 除了visible 以外的值(hidden,auto,scroll )
    • display (table-cell,table-caption,inline-block, flex, inline-flex)
    • position值为(absolute,fixed)
    • fieldset元素
    • 行内块inline-block(元素的display:inline-block)
    • 表格单元格(元素的display:table-ceil,HTML表格默认属性)
    • 弹性盒flex boxes(元素地display:flex或inline-flex)

BFC的作用

  • 利用BFC避免margin重叠。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    <style>
    *{
    margin: 0;
    padding: 0;
    }
    p {
    color: #f55;
    background: yellow;
    width: 200px;
    line-height: 100px;
    text-align:center;
    margin: 30px;
    }
    </style>
    <body>
    <p>猜猜 margin是多少</p>
    <p>猜猜 margin是多少</p>
    </body>

    margin 重叠

    解决办法

    根据第二条,属于同一个BFC的两个相邻的Box会发生margin重叠,所以我们可以设置,两个不同的BFC,也就是我们可以让把第二个p用div包起来,然后激活它使其成为一个BFC

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    <style>
    * {
    margin: 0;
    padding: 0;
    }
    p {
    color: #f55;
    background: yellow;
    width: 200px;
    line-height: 100px;
    text-align: center;
    margin: 30px;
    }
    div {
    overflow: hidden;
    }
    </style>
    <body>
    <p>猜猜 margin是多少</p>
    <div>
    <p>猜猜 margin是多少</p>
    </div>
    </body>

    解决margin 重叠

  • 自适应两栏布局

    根据:每个盒子的margin box的左边,与包含块border box的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    <style>
    .left {
    width: 100px;
    height: 150px;
    float: left;
    background: rgb(139, 214, 78);
    text-align: center;
    line-height: 150px;
    font-size: 20px;
    }

    .right {
    height: 300px;
    background: rgb(170, 54, 236);
    text-align: center;
    line-height: 300px;
    font-size: 40px;
    }
    </style>
    <body>
    <div class="left">LEFT</div>
    <div class="right">RIGHT</div>
    </body>

    float导致元素重叠
    解决办法

    根据:BFC的区域不会与float box重叠。 所以我们让right单独成为一个BFC。。给right加一个 overflow 属性

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    <style>
    .left {
    width: 100px;
    height: 150px;
    float: left;
    background: rgb(139, 214, 78);
    text-align: center;
    line-height: 150px;
    font-size: 20px;
    }

    .right {
    overflow: hidden;
    height: 300px;
    background: rgb(170, 54, 236);
    text-align: center;
    line-height: 300px;
    font-size: 40px;
    }
    </style>
    <body>
    <div class="left">LEFT</div>
    <div class="right">RIGHT</div>
    </body>

    overflow属性解决float导致元素重叠

  • 清楚浮动。

    当我们不给父节点设置高度,子节点设置浮动的时候,会发生高度塌陷,这个时候我们就要清楚浮动。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    <style>
    .par {
    border: 5px solid rgb(91, 243, 30);
    width: 300px;
    }

    .child {
    border: 5px solid rgb(233, 250, 84);
    width:100px;
    height: 100px;
    float: left;
    }
    </style>
    <body>
    <div class="par">
    <div class="child"></div>
    <div class="child"></div>
    </div>
    </body>

    float导致盒子高度塌陷

    根据:计算BFC的高度时,浮动元素也参与计算。 解决办法:给父节点激活BFC

    1
    2
    3
    4
    5
    6
    7
    8
    9
    .par {
    border: 5px solid rgb(91, 243, 30);
    width: 300px;
    overflow: hidden;
    //或者
    //float: left;
    //position: absolute;
    //display: flex;
    }

    清除浮动

文章作者: Darkerbin
文章链接: https://darkerbin.github.io/2020/04/15/BFC/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 解忧杂货店小店员
打赏
  • 微信
    微信
  • 支付寶
    支付寶