从浮动到BFC,深入了解BFC

前言

在我之前的一篇文章关于文档流的文章:文档流是什么?怎么脱离文档流?中有这么一个现象,block块(box1)无视了float元素(box2),而其内部的内联元素被顶了起来,在某些场景下这种情况是我们所不希望看见的。

如图:

我们该怎么解决这个问题呢?这就需要有请我们接下来的正题------BFC

BFC是什么?

BFC即Block Formatting Contexts,按字面意思来讲就是块格式化上下文,也就是说他是一块被格式化的不受外界影响的区域。

html中元素被设置成一个个盒子(不太了解盒模型的同学可以参考一下我这篇文章:css之盒模型),当一个盒子变成BFC以后,其内部的元素也就不会再受到外部的影响,外部也不会受到其内部影响,变成了一个封闭的盒子。

所以简单来将,我们可以将BFC看作是一种CSS属性,触发这种属性以后,元素就会变成一个封闭的盒子。

怎么触发BFC?

那么,我们该怎么触发BFC呢?

BFC并不是某种单独的css属性,BFC依靠别的属性来触发,简单来说,如果我们设置了某些css属性,就会触发BFC。

触发方式
根元素
浮动元素(元素的float不是none)
绝对定位元素(元素的position为absolute或fixed)
display属性中有很多都会触发,常用的来讲不是block就行(flex、inline-block等都可以触发)
overflow值不为visible的块元素
contain值为layot、content或paint的元素
多列容器(元素的column-count或column-width不为auto,包括column-count为1)

BFC解决了哪些问题?

1.避免被浮动元素覆盖

这个其实就是我们开头提到的问题,当块级元素左边有一个左float的元素时,基于float的机制,块级元素将无视它。从而产生了浮动元素覆盖的现象。而块级元素内部的内联元素也遵照机制,浮动在浮动元素周围。

代码:

xml 复制代码
<style>
    .box1{
        width: 100px;
        height: 100px;
        background: blue;
    }
    .box2{
        width: 200px;
        height: 200px;
        background: red;
    }
    .float{
        float: left;
    }
</style>
<body>
    <div class="box1 float">box1</div>
    <div class="box2">box2</div>
</body>

效果:

将box2变成BFC以后我们发现,这一次box2并没有无视box1。究其根本就是因为BFC互相不受影响的性质。

代码:

css 复制代码
.box1{
    width: 100px;
    height: 100px;
    background: blue;
}
.box2{
    overflow: hidden;
    width: 200px;
    height: 200px;
    background: red;
}
.float{
    float: left;
}
</style>
<body>
    <div class="box1 float">box1</div>
    <div class="box2">box2</div>
</body>

效果:

2.清除浮动(高度塌陷)

如果子元素为浮动元素,那么它就会半脱离文档流,这样一来就相当于不在父元素容器内了,父元素就会出现高度塌陷的情况。

代码:

xml 复制代码
<style>
    .box1{
        width: 100px;
        height: 100px;
        border: 1px solid blue; 
    }
    .box2{
        display: block;
        border: 1px solid red; 
    }
    .float{
        float: left;
    }
</style>
<body>
    <div class="box2">
        <div class="box1 float">
        </div>
    </div>
</body>

效果:

但是如果我们给父元素设置BFC,那么子元素虽然半脱离文档流,但是仍然相当于处于父元素这个不受外部影响的容器内,所以就可以撑起父元素的高度。

代码:

xml 复制代码
<style>
    .box1{
        width: 100px;
        height: 100px;
        border: 1px solid blue; 
    }
    .box2{
        overflow: hidden;
        display: block;
        border: 1px solid red; 
    }
    .float{
        float: left;
    }
</style>
<body>
    <div class="box2">
        <div class="box1 float">
        </div>
    </div>
</body>

效果:

3.外边距重叠

当两个相邻的元素之间都设置有外边距时,就会出现外边距重叠的情况(只保留成大的那个),父子元素之间也会出现。

代码:

xml 复制代码
<style>
    .box1{
        width: 100px;
        height: 100px;
        border: 1px solid blue; 
        margin-bottom: 100px;
    }
    .box2{
        width: 100px;
        height: 100px;
        border: 1px solid red; 
        margin-top: 100px;
    }
</style>
<body>
    <div class="box1">
    </div>
    <div class="box2">     
    </div>
</body>

效果:

这个属于是正常现象,但是我们有时候并不希望这样,这时候就可以通过用BFC元素去包裹他们,从而取消两个元素之间的互相影响。

代码:

xml 复制代码
<style>
    .bfc{
        overflow: hidden;
    }
    .box1{
        width: 100px;
        height: 100px;
        border: 1px solid blue; 
        margin-bottom: 100px;
    }
    .box2{
        width: 100px;
        height: 100px;
        border: 1px solid red; 
        margin-top: 100px;
    }
</style>
<body>
    <div class="bfc">
        <div class="box1">
        </div>
    </div>
    <div class="bfc">
        <div class="box2">     
        </div>
    </div>
</body>

效果:

总结

BFC是作为前端的入门问题,在现在的面试过程中也经常会问到,想要真正理解它还是需要上手去操作、去实验。在写代码的过程中很多东西我们不仅要知其所以,还要知其所以然,只有这样才能逐步成长,解决衍生问题乃至利用它去开发。

相关推荐
之恒君几秒前
script 标签中的 async 和 defer 的区别
前端·javascript
浪浪山_大橙子3 分钟前
使用Electron+Vue3开发Qwen3 2B桌面应用:从想法到实现的完整指南
前端·人工智能
狗哥哥6 分钟前
聊聊设计模式在 Vue 3 业务开发中的落地——从一次代码重构说起
前端·架构
shenzhenNBA17 分钟前
如何在python文件中使用日志功能?简单版本
java·前端·python·日志·log
掘金泥石流19 分钟前
分享下我创业烧了 几十万的 AI Coding 经验
前端·javascript·后端
用户479492835691521 分钟前
JavaScript 为什么选择原型链?从第一性原理聊聊这个设计
前端·javascript
new code Boy26 分钟前
vscode左侧栏图标及目录恢复
前端·javascript
唐诗27 分钟前
Git提交信息太乱?AI一键美化!一行命令拯救你的项目历史🚀
前端·ai编程
涔溪42 分钟前
有哪些常见的Vite插件及其作用?
前端·vue.js·vite
糖墨夕42 分钟前
从一行代码看TypeScript的精准与陷阱:空值合并vs逻辑或
前端·typescript