一、什么是BFC
BFC即是块级格式上下文,绝定元素的内容如何渲染以及与其它元素的关系和交互,简单理解就是BFC是一个容器,BFC中的元素相当于容器中的物品,将物品放置在箱子中可以起到隔离作用,不会受其它箱子中的物品的影响,反之亦然
BFC有以下5个规则:
- BFC有隔离作用,内部元素不会受外部元素的影响,反之亦然
- 一个元素只能存在一个BFC中,如果同时存在两个BFC中就会违反隔离规则
- BFC中的元素按正常流排序,元素之间的间隙由元素的外边距(margin)控制
- BFC中的内容不会与外部的浮动元素重叠(可以应用两栏布局)
- 计算BFC的高度,需要包括BFC内的浮动元素的高度(可以解决浮动元素影响下的盒子高度塌陷的问题)
二、创建BFC
- 设置float属性不为none
- positon设置为absolute或者fixed
- display设置为inline-block、table-cell(相当于td或者th元素)、table-caption(相当于caption元素)、flex、inline-flex
- overflow不为visible
三、BFC应用
- 清除浮动
(1)当一个元素被定义浮动后,附近的文字,即使不是相邻关系,也会围绕着它,解决办法,给浮动元素的容器设置BFC,这里要注意,是给容器,而不是给元素设置BFC
<div style="overflow: hidden;">
<p style="float: left;">你好</p>
</div>
<p>我来了</p>
上一段代码中,如果不给div设置hidden属性,则文字“你好”和文字“我来了”是一行展示的,设置了BFC后则正常的两行显示
(2)浮动的元素会脱离正常文档流,如果这个元素附近有其它元素,且该元素处于正常文档流中,则两个元素会重叠
<p style="float: left;">浮动</p>
<div style="width: 100px;height: 100px;background: lightcoral;"></div>
效果如下:
现在我们来使用BFC来解决这个问题,给div设置了overflow:hidden后效果如下:
(3)高度塌陷
<div style="border: 1px solid gold;">
<section style="float: left;height: 100px;">left</section>
</div>
效果如下图:
div的浮动子元素没有撑开div容器,导致border是一条线,我们给div设置BFC后,则可以正常撑开div盒子了
现在介绍高度塌陷的几个解决办法
(1)给容器也设置浮动,缺点:会影响父元素之后的元素
(2)给父元素添加一个固定的高度,但是这种方式仅仅适用于知道子元素的高度的情况,且不利于代码维护
(3)给浮动元素后面增加一个空元素,设置clear:both,这种方式会增加无意义的标签,不利于代码维护
(4)给容器添加伪类,设置 .box::after{ display:block; overflow:hidden; content:"", height:0; clear:both}
- 解决外边垂直方向重合(margin重叠问题)
<p style="margin-bottom: 20px;width: 50px;height: 50px;background: seagreen;"></p>
<p style="margin-top: 20px;width: 50px;height: 50px;background: sienna;"></p>
效果如下:
<p style="margin-bottom: 20px;width: 50px;height: 50px;background: seagreen;"></p>
<div style="overflow: hidden;">
<p style="margin-top: 20px;width: 50px;height: 50px;background: sienna;"></p>
</div>
我们本来希望垂直边距是40,但是兄弟元素垂直方向的外边距是取最大值而不是取和,所以垂直变剧是20而不是40,我们可以通过BFC来消除元素之间的影响,我们给第二个元素用容器div包裹且设置BFC则可以获取正确的垂直边距了,效果如下
- 宽度自适应的两列布局
当没有设置BFC时,利用float来实现两列布局时会出现如下现象,当右侧高度超过左侧高度时会出现下图的现象,我们可以给右侧元素的容器设置BFC则可以解决这个问题
<div style="background: slateblue;width: 200px;float: left;">dgsfsgfgfgndn</div>
<div style="background: lightblue;overflow: hidden;">
dgsfsgfgfgndndgsfsgfgfgndndgsfsgfgfgndndgsfsgfgfgndndgsfsgfgfgndn
dgsfsgfgfgndndgsfsgfgfgndndgsfsgfgfgndndgsfsgfgfgndndgsfsgfgfgndn
dgsfsgfgfgndndgsfsgfgfgndndgsfsgfgfgndndgsfsgfgfgndndgsfsgfgfgndn
</div>
效果如下图:
实现两列布局的四种方式:
(1)左侧:width:200px;float:left; 右侧:overflow:hidden
(2)左侧:width:200px;float:left; 右侧:margin-left:200px
(3)左侧:position: absolute;top:0;left: 0; 右侧:margin-left:200px
(4)左侧:position: absolute;top:0;left: 0; 右侧:position: absolute;top: 0;right: 0;left: 200px;width: 100%