BFC的神秘面纱

面试的时候,面试官有的时候会让你说说BFC。
那到底什么是BFC,什么条件下可以创建BFC,什么元素默认就是BFC的,什么css属性遵循什么方式就可以呈现BFC呢?
BFC的英文全写是Block formatting context,中文译文是块格式化上下文,是Web页面的可视CSS渲染的一部分,是块盒子的布局过程发生的区域,也是浮动元素与其他元素交互的区域。

可能直接理解什么是BFC困难了一些,我们可以先了解一下文档的三种布局定位方案。

一、三种文档流的定位方案

常规流(Normal flow)

  • 常规流、文档流、普通文档流、常规文档流
  • 所有元素,默认情况下,都属于常规流布局
  • 总体规则:块盒独占一行,行盒水平依次排列
  • 包含块(containing block):每个盒子都有它的包含块,包含块决定了盒子的排列区域。
  • 绝大部分情况下:盒子的包含块,为其父元素的内容盒

浮动(Floats)

  • 左浮动元素尽量靠左、靠上,右浮动同理
  • 这导致常规流环绕在它的周边,除非设置 clear 属性
  • 浮动元素不会影响块级元素的布局
  • 浮动元素会影响行内元素的布局,让其围绕在自己周围,撑大父级元素,从而间接影响块级元素布局
  • 最高点不会超过当前行的最高点、它前面的浮动元素的最高点
  • 不超过它的包含块,除非元素本身已经比包含块更宽
  • 行内元素出现在左浮动元素的右边和右浮动元素的左边,左浮动元素的左边和右浮动元素的右边是不会摆放浮动元素的

绝对定位(Absolute positioning)
绝对定位方案,盒从常规流中被移除,不影响常规流的布局;
它的定位相对于它的包含块,相关CSS属性:top、bottom、left、right;
如果元素的属性position为absolute或fixed,它是绝对定位元素;
对于position: absolute,元素定位将相对于上级元素中最近的一个relative、fixed、absolute,如果没有则相对于body;

二、创建BFC的方式

下列方式会创建块格式化上下文:

  • 根元素()
  • 浮动元素(元素的 float 不是 none)
  • 绝对定位元素(元素的 position 为 absolute 或 fixed)
  • 行内块元素(元素的 display 为 inline-block)
  • 表格单元格(元素的 display 为 table-cell,HTML表格单元格默认为该值)
  • 表格标题(元素的 display 为 table-caption,HTML表格标题默认为该值)
  • 匿名表格单元格元素(元素的 display 为 table、table-row、 table-row-group、table-header-group、table-footer-group(分别是HTML
    table、row、tbody、thead、tfoot 的默认属性)或 inline-table)
  • overflow 值不为 visible 的块元素
  • display 值为 flow-root 的元素
  • contain 值为 layout、content 或 paint 的元素
  • 弹性元素(display 为 flex 或 inline-flex 元素的直接子元素)
  • 网格元素(display 为 grid 或 inline-grid 元素的直接子元素)
  • 多列容器(元素的 column-count 或 column-width 不为 auto,包括 column-count 为 1)
  • column-span 为 all 的元素始终会创建一个新的BFC,即使该元素没有包裹在一个多列容器中(标准变更,Chrome bug)。

根元素本身就是一个BFC元素,它具有自身的扩展性,承接了header、body等元素。
浮动元素float不管是left还是right都会创建一个BFC,只是我们需要注意,float元素会脱离文档正常布局,我们需要通过一定的方式清除浮动,比如overflow设置成hidden等。
而绝对定位也是很好的BFC,比如设置移动端底部的导航等。
其它方式只要遵循上述之一即是正常的BFC。

三、创建BFC的作用

比较常见的BFC的作用就是用来清除浮动、分离兄弟元素、解决margin塌陷问题等
1、清除浮动
我们利用ul的方式来进行布局,ul标签含有两个li标签,li标签是同级别的,如果按照默认的方式,那么li元素内容在ul没有设置高度的时候,自动撑起来ul标签。

 <ul style="background: burlywood;">
   <li style="width: 800px;height: 200px;background: red;"></li>
   <li style="width: 500px;height: 200px;background: blue;"></li>
 </ul>

如下图所示:
在这里插入图片描述
这个时候,我们在li标签上加一个float:left,
在这里插入图片描述
很显然,ul父元素本身的颜色消失了,也就是说,float后,父元素没有被子元素支撑起来,那么我们可以在父级元素上加入overflow:hidden的属性或者display:flow-root(注意兼容性),如下:

<ul style="background: burlywood;overflow: hidden;">
  <li style="width: 800px;height: 200px;background: red;margin: 0;float: left;"></li>
   <li style="width: 500px;height: 200px;background: blue;margin: 0;float: left;"></li>
 </ul>

如下图所示:
在这里插入图片描述

2、分离兄弟元素
可以利用BFC对兄弟标签元素进行修饰,比如说,在body下方,进行绝对定位的布局,将两个同级别的li标签float不同方向等等。

3、margin塌陷的解决
原理:父子嵌套元素在垂直方向的margin,父子元素是结合在一起的,他们两个的margi会取其中最大的值。
正常情况下,父级元素应该相对浏览器进行定位,子级相对父级定位。
但由于margin的塌陷,父级相对浏览器定位.而子级没有相对父级定位,子级相对父级,就像坍塌了一样。
代码如下:

<div style="background: red;height: 200px;width: 400px;margin-bottom: 30px;color: #fff;">div1</div>
<div style="background: red;height: 200px;width: 400px;margin-top: 50px;color: #fff;">div2</div>

图形如下:
在这里插入图片描述
这里就是相当于div1的margin-bottom的30px塌陷在了其兄弟元素的margin-top的50px中了。
这个时候,我们可以将div1套一个父级,这个父级是跟div2同级的,并且,将这个父级设置overflow: hidden。

代码如下:

<div style="overflow: hidden;">
  <div style="background: red;height: 200px;width: 400px;margin-bottom: 30px;color: #fff;">div1</div>
 </div>
 <div style="background: red;height: 200px;width: 400px;margin-top: 50px;color: #fff;">div2</div>

展示图片如下:
在这里插入图片描述
这就是BFC,也是我个人比较浅显的理解,将它总结一下,对以后布局页面有一些帮助。

参考:
1、CSS中重要的BFC:https://segmentfault.com/a/1190000013023485
2、MDN的Block formatting context:https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Block_formatting_context
3、浅析BFC及其作用:https://blog.csdn.net/riddle1981/article/details/52126522

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值