BFC "苦"前端久矣!

用户头像
大导演
关注
发布于: 2020 年 07 月 30 日
BFC "苦"前端久矣!



为什么起这个标题?相信大家在面试过程中都被问及过 BFC,这着实不是一个好问题。



BFC 发生在 Normal flow,而 Normal flow 是 CSS Layout 中最基本的布局方式。理解 BFC,对理解 CSS 布局大有裨益。

概述



BFC(Block Formatting Contexts)直译“块级格式化上下文”。W3C CSS 2.1 中有这样的描述:

Floats, absolutely positioned elements, block containers (such as inline-blocks, table-cells, and table-captions) that are not block boxes, and block boxes with 'overflow' other than 'visible' (except when that value has been propagated to the viewport) establish new block formatting contexts for their contents.



原文请戳这里

啥,啥,啥,这都说了啥?

浮动、绝对定位的元素,不是 block boxesblock containers(诸如 inline-blocks、table-cells 以及 table-captions 等), 以及 overflow 的值不是 visible block boxes,会创建新的 BFC。



如果说定义中的 block containers 还可以知道是啥意思,那 block boxes 可能就需要我们在标准中再找找答案了。不难发现,标准中还是给出了 block boxes 的定义的。



Block-level boxes that are also block containers are called block boxes.



这句话可以说是很全乎了。涉及到了 3 个名词,block-level boxesblock containersblock boxes。意思就是说 block boxes = block-level boxes + block containers



简言之:

block container 可以容纳 BFC;

block-level box 可以放入 BFC;

block boxes overflow 的值是 visible,就和“父” BFC 合并

应用



  • 阻止 margin 折叠



margin 折叠发生在 BFC 内部。请看下面的代码:



<style></style>
<div class="container">
<div class="box">1-1</div>
<div class="box">1-2</div>
<div class="box">1-3</div>
<div class="box">1-4</div>
<div class="box">1-5</div>
</div>



margin 折叠



.container 是 block boxes,且 overflow 的值不是 visible,所以 .container 是 BFC,可以看到,每一个 .box 的 margin 都是 20px, 两个 .box 之间的 margin 仍然是 20px 而非 40px。这就是著名的 margin 折叠。而 margin 折叠只会发生在 BFC 内部。



这样的设计并不符合人类的直觉,那么如何阻止 margin 折叠呢?既然 margin 折叠发生在 BFC 内部,那阻止 margin 折叠也十分简单 —— 创建新的 BFC。



<style></style>
<div class="container">
<div class="box">2-1</div>
<div class="box">2-2</div>
<div class="box">2-3</div>
<div class="wrapper">
<div class="box">2-4</div>
<div class="box">2-5</div>
</div>
</div>



阻止 margin 折叠



从上图中可以看到,.box 2-3 和 .wrapper 发生了 margin 折叠,它们同处一个 BFC;.box 2-4 和 .wrapper 并没有发生 margin 折叠,也就是说 2-3 和 2-4 之间的留白是 50px



如果把 .wrapperoverflow 设置成 visible,可以发现 .box 2-3 和 .wrapper.wrapper.box 2-4 都发生了 margin 折叠, 2-3 和 2-4 之间的留白为 30px。如下图所示:



overflow 值为 visible 的 margin 折叠

所以,overflow:visibleblock boxes,是一种特例,它里面是 block-level box,外面也是 block-level box,发生了合并,共处同一个 BFC。



  • 清除内部浮动



我们先来看浮动的情况,代码如下:



<style></style>
<div>
<div class="float">我是浮动的</div>
<div class="box"></div>
</div>



元素浮动

.float 是浮动的,脱离文档流,所以 .float 叠在了 .box 的上面。可以利用 BFC 来清除浮动的影响,给 .box 添加 overflow: hidden 产生新的 BFC。如图:



清除浮动

小结



如果一个元素具有 BFC,内部子元素再怎么翻江倒海、翻云覆雨,都不会影响外部的元素。所以,BFC 元素是不可能发生 margin 折叠的,因为 margin 折叠是会影响外部的元素的;BFC 元素也可以用来清除浮动的影响,因为如果不清除,子元素浮动则父元素高度塌陷,必然会影响后面元素布局和定位,这显然有违 BFC 元素的子元素不会影响外部元素的设定。



好了,今天的文章到这里就结束了。如果对你有所帮助,欢迎点赞转发~



发布于: 2020 年 07 月 30 日 阅读数: 141
用户头像

大导演

关注

导演出品,必属精品 2019.01.15 加入

还未添加个人简介

评论 (1 条评论)

发布
用户头像
文章被置顶了,请添加一下封面,更美观,也有利于置顶顺序~最好再丰富一下标题
2020 年 07 月 30 日 17:59
回复
好的,安排
2020 年 07 月 30 日 21:22
回复
没有更多了
BFC "苦"前端久矣!