阅读 89

一文理解CSS中BFC的含义及其作用

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

1. 何为BFC

BFC 的全程为块格式化上下文(Block Formatting Context),在 MDN 定义如下:

块格式化上下文(Block Formatting Context,BFC) 是Web页面的可视CSS渲染的一部分,是块盒子的布局过程发生的区域,也是浮动元素与其他元素交互的区域。

简单理解为,BFC 是一个完全独立的盒子,内部的元素无论样式是什么,都不会影响到盒子外部的布局。

2. 触发BFC

  • 根元素<html>
  • 浮动元素(float不为none
  • 固定定位、绝对定位元素(positionabsolutefixed
  • 行内块元素(display: inline-block
  • 表格单元格(display: table-cell)默认
  • 表格标题(display: table-caption)默认
  • overflow不为visible
  • 弹性元素(display: flex
  • 网格元素(display: grid
  • ...

3. 利用BFC解决问题

1. 外边距塌陷

有如下代码,两个盒子,外边距margin都设置为50px,理应两个盒子的间距应该为100px,但其真实间距为50px

这是因为发生了外边距塌陷问题,两个盒子的margin重叠到了一起,相互影响。

<style>
    .son {
        width: 100px;
        height: 100px;
        background-color: blue;
        margin: 50px;
    }
</style>
<body>
    <div class="son"></div>
    <div class="son"></div>
</body>
复制代码

可以利用 BFC 特性来解决外边距塌陷问题。将这两个盒子,分别放入两个 BFC 区域中,因为 BFC 是一个完全独立的盒子,内部的元素不会影响到外部区域。

将以上代码修改为如下即可解决,两盒子间距变为100px

<style>
    .father {
        background-color: yellow;
        /* 触发BFC */
        overflow: hidden;
    }
    .son {
        width: 100px;
        height: 100px;
        background-color: blue;
        margin: 50px;
    }
</style>
<body>
    <div class="father">
        <div class="son"></div>
    </div>
    <div class="father">
        <div class="son"></div>
    </div>
</body>
复制代码

2. 内边距包含塌陷

如下代码,父子关系的盒子中,给子盒子加了margin-top,父盒子也会跟着一起下去。

<style>
    .top {
        height: 50px;
        width: 200px;
        background-color: pink;
    }
    .father {
        width: 200px;
        height: 200px;
        background-color: yellow;
    }
    .son {
        width: 100px;
        height: 100px;
        background-color: blue;
        margin-top: 50px;
    }
</style>
<body>
    <div class="top">顶部元素</div>
    <div class="father">
        <div class="son"></div>
    </div>
</body>
复制代码

可以利用 BFC 特性来解决包含塌陷问题。将父盒子设置为一个 BFC,这样父盒子内部的样式就不会影响到外部的布局了。

使用overflow: hidden触发 BFC:

<style>
    .top {
        height: 50px;
        width: 200px;
        background-color: pink;
    }
    .father {
        width: 200px;
        height: 200px;
        background-color: yellow;
        /* 触发BFC */
        overflow: hidden;
    }
    .son {
        width: 100px;
        height: 100px;
        background-color: blue;
        margin-top: 50px;
    }
</style>
<body>
    <div class="top">顶部元素</div>
    <div class="father">
        <div class="son"></div>
    </div>
</body>
复制代码

3. 清除浮动带来的影响

如下代码,一个没有设置高度的父盒子,里面一个子盒子设置了浮动,那么父盒子失去了高度,不显示在页面上了。

<style>
    .top {
        height: 50px;
        width: 200px;
        background-color: pink;
    }
    .father {
        width: 200px;
        background-color: yellow;
    }
    .son {
        width: 100px;
        height: 100px;
        background-color: blue;
        float: left;
    }
</style>
<body>
    <div class="top">顶部元素</div>
    <div class="father">
        <div class="son"></div>
    </div>
</body>
复制代码

可以利用 BFC 特性来解决浮动问题。因为父盒子没有高度了,必然影响了外部元素的布局。那将父盒子触发 BFC,这样父盒子内部的子盒子就不会影响到外部布局了:

<style>
    .top {
        height: 50px;
        width: 200px;
        background-color: pink;
    }
    .father {
        width: 200px;
        background-color: yellow;
        /* 触发BFC */
        overflow: hidden;
    }
    .son {
        width: 100px;
        height: 100px;
        background-color: blue;
        float: left;
    }
</style>
<body>
    <div class="top">顶部元素</div>
    <div class="father">
        <div class="son"></div>
    </div>
</body>
复制代码

4. 阻止浮动元素覆盖标准流

如下代码,两个为兄弟关系的盒子,其中一个盒子设置浮动时,另一个还是标准流,那么浮动的盒子会覆盖标准流的盒子,显示出如下效果:

<style>
    .div1 {
        width: 100px;
        height: 100px;
        background-color: blue;
        float: left;
    }
    .div2 {
        height: 300px;
        background-color: yellow;
        font-size: 26px;
    }
</style>
<body>
    <div class="div1"></div>
    <div class="div2">
        我被挤开了。我被挤开了。我被挤开了。我被挤开了。我被挤开了。我被挤开了。我被挤开了。我被挤开了。我被挤开了。我被挤开了。我被挤开了。我被挤开了。
    </div>
</body>
复制代码

可以看到,标准流的盒子(黄色的盒子)中的文字受到了浮动流盒子(蓝色盒子)的影响,文字环绕蓝色盒子周围。

可以利用 BFC 特性来解决这个问题。标准流盒子触发 BFC,浮动元素就不会覆盖标准流盒子了,也不会影响到里面的文字:

<style>
    .div1 {
        width: 100px;
        height: 100px;
        background-color: blue;
        float: left;
    }
    .div2 {
        height: 300px;
        background-color: yellow;
        font-size: 26px;
        /* 触发BFC */
        overflow: hidden;
    }
</style>
<body>
    <div class="div1"></div>
    <div class="div2">
        我被挤开了。我被挤开了。我被挤开了。我被挤开了。我被挤开了。我被挤开了。我被挤开了。我被挤开了。我被挤开了。我被挤开了。我被挤开了。我被挤开了。
    </div>
</body>
复制代码

而且,还实现了黄色盒子的宽度自适应效果,根据蓝色盒子的宽度,自动调整宽度。

文章分类
前端
文章标签