说起bfc,第一印象就是这哥们不是清浮动用的么?浮动使用不当可能会造成页面的塌陷,如果触发了BFC就不会造成页面的塌陷,具体原理?不太清楚。。。。。某日在一论坛网站看到了一些关于BFC的介绍,“当你在修改样式的时候,就会在不知不觉的时候触发了神奇的BFC,用了却不知晓。”突然觉得这哥们真的太低调了,以前从来没有认真的去探讨过他。
先来说说什么是BFC(Block Formatting Context)
box: 写CSS样式时,对一个元素设置css,我们首先要知道这个元素是块级元素(block,list-item, table等)还是行内元素( inline, inline-block, inline-table等),也就是去知道哪种类型的box, 不同类型的 box, 会参与不同的 Formatting Context(一个决定如何渲染文档的容器),因此box内的元素会以不同的方式渲染。
Formatting Context: 指页面中一个渲染区域,并且拥有一套渲染规则,它决定了其子元素如何定位,以及与其他元素的相互关系和作用。
BFC定义: 而BFC(Block Formatting Context)作用就是格式化块级(block)盒子,它会生成一个独立的块级渲染区域,该区域拥有一套渲染规则来约束块级盒子的布局,不受外界的干扰
怎样去触发BFC
满足下列CSS声明之一的元素便会生成BFC:
根元素或其它包含它的元素
float的值不为none;
overflow的值不为visible;
position的值不为static;
display的值为inline-block、table-cell、table-caption;
flex boxes (元素的display: flex或inline-flex);
那么触发了BFC,布局会怎样呢?
1、内部的元素会在垂直方向一个接一个地排列,可以理解为是BFC中的一个常规流
2、元素垂直方向的距离由margin决定,即属于同一个BFC的两个相邻盒子的margin可能会发生重叠
3、每个元素的左外边距与包含块的左边界相接触(从左往右,否则相反),即使存在浮动也是如此,这说明BFC中的子元素不会超出它的包含块
4、BFC的区域不会与float元素区域重叠
5、计算BFC的高度时,浮动子元素也参与计算
6、BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素,反之亦然
BFC到底有个啥用呢?
1.解决上下相邻的两个元素上下方向的margin重叠的bug。这个bug长的是下面的那种样子
<style>
*{margin:0;padding:0;}
.box p{
margin:20px 0;
background: #E5F6FE;
text-indent:3rem;
}
</style>
<body>
<div class="box">
<p>1我的下margin与下面兄弟的上margin重合了</p>
<p>2我是无辜的</p>
<p>3我的上margin和上面兄弟的下margin重合了</p>
</div>
</body>
上面的第一个p下margin是20px,第二个p上margin是20px,两者应该是40才对吧?这bug整的让人搓手不及呀
这个时候BFC就该闪亮登场啦,赶紧去召唤BFC吧,如何召唤呢,参照上面。。。
给p加一个父元素div并且加上overflow: hidden;形成一个干净的块级渲染区域
<body>
<div class="box">
<p>1我的下margin与下面兄弟的上margin重合了</p>
<div style="overflow: hidden;">
<p>2我是无辜的</p>
</div>
<p>3我的上margin和上面兄弟的下margin重合了</p>
</div>
</body>
bug立即就消失了
2.清除浮动;
这个太常用了,只要满足触发BFC的css条件就能清除浮动。比如给浮动元素的父级加上overflow: hidden;
就可以清除浮动了,原理就是父级触发了BFC,形成一个干净的块级渲染区域,所以他内部的元素就不会影响外面的布局,BFC就把浮动的子元素高度当做了自己内部的高度去处理溢出,所以外面看起来是清除了浮动。
3.解决侵占浮动元素的问题;
我们都知道元素设置了浮动之后,就会脱离标准文档流。那么他浮动之前的正常文档流的位置会被其他不脱离文档流的元素所占据。
举个栗子
<style>
*{margin:0;padding:0;}
.div1{
background: rgb(216, 92, 92);
float: left;
width:100px;
height:100px;
}
.div2{
background: rgb(228, 206, 10);
width:200px;
height:200px;
}
</style>
<body>
<div class="div1">我是div1</div>
<div class="div2">我是div2</div>
</body>
这样布局的结果就是div1会浮在div2上面,或者是说div2会占据div1的位置;
如果div1不想让div2占据我的位置,两种思路:
1.div1已经浮动了,也就是div1本身已经触发了bfc。如果需要保留位置,再给它套一层父级,父级身上加入能触发BFC的css,比如overflow: hidden;
等。
2.div2不去占用div1的位置,即给div2创造BFC的空间,不去受外界的影响。那么触发div2的BFC,可以是给div2加float:left;
,或者加上overflow: hidden;
示例如下:
.div2{
background: rgb(228, 206, 10);
width:200px;
height:200px;
overflow: hidden;
}
写在最后:
个人的理解就是,BFC就是一种环境或者容器,在BFC里面的box和box里面的子集不会去受其他元素的影响。
对于BFC的概念在CSS2.1 spec 有详细的说明
CSS2.1不止BFC,还有IFC(这个还没有具体去看)
CSS3 还提出了 GFC 和 FFC。
前端之路,任重而道远,愿你我一步一脚印