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

相关推荐
醉方休几秒前
Webpack loader 的执行机制
前端·webpack·rust
前端老宋Running9 分钟前
一次从“卡顿地狱”到“丝般顺滑”的 React 搜索优化实战
前端·react.js·掘金日报
隔壁的大叔9 分钟前
如何自己构建一个Markdown增量渲染器
前端·javascript
用户44455436542611 分钟前
Android的自定义View
前端
WILLF12 分钟前
HTML iframe 标签
前端·javascript
枫,为落叶29 分钟前
Axios使用教程(一)
前端
小章鱼学前端34 分钟前
2025 年最新 Fabric.js 实战:一个完整可上线的图片选区标注组件(含全部源码).
前端·vue.js
ohyeah35 分钟前
JavaScript 词法作用域、作用域链与闭包:从代码看机制
前端·javascript
流星稍逝37 分钟前
手搓一个简简单单进度条
前端
倚栏听风雨1 小时前
详解 TypeScript 中,async 和 await
前端