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

相关推荐
Hamm几秒前
咦,你的Git仓库贡献者里怎么有这么多大佬???
前端·git·github
陈卓41033 分钟前
Redis-限流方案
前端·redis·bootstrap
顾林海42 分钟前
Flutter Dart 运算符全面解析
android·前端
七月丶1 小时前
🚀 现代 Web 开发:如何优雅地管理前端版本信息?
前端
漫步云端的码农1 小时前
Three.js场景渲染优化
前端·性能优化·three.js
悬炫1 小时前
赋能大模型:ant-design系列组件的文档知识库搭建
前端·ai 编程
用户108386386801 小时前
95%开发者不知道的调试黑科技:Apipost让WebSocket开发效率翻倍的秘密
前端·后端
稀土君1 小时前
👏 用idea传递无限可能!AI FOR CODE挑战赛「创意赛道」作品提交指南
前端·人工智能·trae
OpenTiny社区1 小时前
Node.js 技术原理分析系列 4—— 使用 Chrome DevTools 分析 Node.js 性能问题
前端·开源·node.js·opentiny
写不出代码真君2 小时前
Proxy和defineProperty
前端·javascript