前言
说起BFC,一些不熟悉的童鞋往往会有两种情况:
- 无形中用了BFC,但是不知道有这回事
- 请教过大佬,听过BFC大名,然后CV了一段
overflow: hidden
解决了问题。然后不刨根问底,笔者曾经也是其中的一员。思维不清晰肿么办?问谷歌娘呗~看了好多文章,知道自己没有过目不忘的本事,还是觉得要自己动手写写,一来加深印象,二来方便日后追溯,故撰此文。
什么是BFC?
w3c是这么解释的:
浮动元素和绝对定位元素,非块级盒子的块级容器(例如 inline-blocks, table-cells, 和 table-captions),以及overflow值不为“visiable”的块级盒子,都会为他们的内容创建新的
块级格式化上下文
(block formatting context)。
请注意,BFC并不是一个css属性,也不是一段代码,而是css中基于box的一个布局对象,它是页面中的一块渲染区域,并且有一套渲染规则,它决定了其子元素将如何定位,以及和其他元素的关系和相互作用。明确地,它是一个独立的盒子,并且这个独立的盒子内部布局不受外界影响,当然,BFC也不会影响到外面的元素。
成为BFC的条件
其实在w3c规范中已经简单罗列了称为BFC的基本条件,但我们还是详细说明下,保持记忆脉络清晰。
一个BFC是一个HTML盒子并且至少满足下列条件中的任何一个:
float
的值不为noneposition
的值不为static或者relativedisplay
的值为 table-cell, table-caption, inline-block,flex, 或者 inline-flex中的其中一个overflow
的值不为visible- 根元素
BFC的特性
BFC的特性可以总结为以下几点:
- BFC内部,盒子由上至下按顺序进行排列,其间隙由盒子的外边距决定,并且,当同一个BFC中的两个盒子同时具有相对方向的外边距时,其外边距还会发生叠加(Margin Collapse)
- BFC内部,无论是浮动盒子还是普通盒子,其左总是与包含块的左边相接触
- BFC 区域不会与float box区域相叠加
- BFC内外布局不会相互影响
- 计算BFC高度的时候,浮动元素的高度也计算在内
触发BFC
根据成为BFC的条件,一般有以下4种方法触发BFC:
- display: table
前后带有换行符,我们一般也不常用
- overflow: scroll
可能会出现不想要的滚动条,丑
- float: left
万一我们不想让元素浮动呢?
- overflow: hidden
比较完美的创建BFC的方案,副作用较小,仿佛遇到了我的心动女生
BFC能解决的问题
1. 解决margin collapse(外边距叠加)
什么是外边距叠加?复述一遍:
当同一个BFC中的两个盒子同时具有相对方向的外边距时,外边距会发生叠加(Margin Collapse),当兄弟盒子的外边距不一样时,将以最大的那个外边距为准。
如上述展示,我们将内部灰色盒子的垂重margin设置为和自身高度一样,按自然思维两个盒子之间的距离应该是两个盒子的高度,由于外边距叠加,只剩下一个身位的高度。
要解决上述问题,设想:如果他们属于不同的BFC,他们之间的外边距将不会折叠。我们给其中的一个盒子外部包裹一层父盒子,并成为一个BFC。
现在可以清楚地看到,第一个盒子由于不再和其他其他同类名盒子在同一个BFC中,它和第二个盒子的外边距并没有发生叠加
总的来讲,外边距叠加本身是由BFC引起的,但是现在我们要用BFC来解决这个问题,颇有点以毒攻毒的味道。
2.清除浮动
想想那些年我们一起清除过的浮动,解决方式是什么?clear: both?父元素一起浮动?这些都没错,但是作为前端开发者,我们解决问题应该需要掌握多种技能,以适应多种不同的问题环境,偶尔还可以装装X:)
我们往往会遇到这样一种情况,父元素高度自适应,子元素浮动,因为不在同一文档流中,父元素的高度会坍塌,如下所示:
这个时候,我们可以利用BFC来解决问题,根据是:计算BFC高度的时候,浮动元素的高度也计算在内
我们通过添加overflow: hidden
,在容器中创建一个新的BFC,效果如下:
只需要添加一个属性,效果不错吧~
3.实现两栏布局
一般的后台管理系统,很多都是传统的左菜单右内容的两栏布局,我们经常会选择左栏浮动,右边设置左padding或者margin的思路来实现这一做法,其实利用BFC也可以创建两栏布局,根据是:BFC 区域不会与float box区域相叠加
See the Pen XpLJXm by junnan shi (@BenjaminShih) on CodePen.
简单吧~
结尾
前端知识网络错综复杂,包括各种hack和黑科技,难免疏漏,或有不对之处,欢迎交流