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

相关推荐
也无晴也无风雨1 小时前
深入剖析输入URL按下回车,浏览器做了什么
前端·后端·计算机网络
Martin -Tang1 小时前
Vue 3 中,ref 和 reactive的区别
前端·javascript·vue.js
FakeOccupational3 小时前
nodejs 020: React语法规则 props和state
前端·javascript·react.js
放逐者-保持本心,方可放逐3 小时前
react 组件应用
开发语言·前端·javascript·react.js·前端框架
曹天骄4 小时前
next中服务端组件共享接口数据
前端·javascript·react.js
阮少年、4 小时前
java后台生成模拟聊天截图并返回给前端
java·开发语言·前端
郝晨妤6 小时前
鸿蒙ArkTS和TS有什么区别?
前端·javascript·typescript·鸿蒙
AvatarGiser6 小时前
《ElementPlus 与 ElementUI 差异集合》Icon 图标 More 差异说明
前端·vue.js·elementui
喝旺仔la6 小时前
vue的样式知识点
前端·javascript·vue.js
别忘了微笑_cuicui6 小时前
elementUI中2个日期组件实现开始时间、结束时间(禁用日期面板、控制开始时间不能超过结束时间的时分秒)实现方案
前端·javascript·elementui