BFC的生成

在实现CSS的布局时,假设我们不知道BFC的话,很多地方我们生成了BFC但是不知道.在布局中,一个元素是block元素还是inline元素是必须要知道的.而BFC就是用来格式化块状元素盒子,同样还有管理内连盒子的IFC等.那首先就来了解一下什么是FC.

FC: Formatting Context指的是页面中的一个渲染区域,并且拥有自己的渲染规则.决定子元素如何定位,以及和其他元素的相互作用和联系.
BFC: 块级格式化上下文, 是一个独立的块级渲染区域,只针对块级元素,有一套自己的渲染规则来约束块级盒子,与外部无关.

既然BFC是一块独立的渲染区域,那么这块区域在哪里,有多大, 这就有生成BDC的元素决定,CSS2.1中规定, 满足以下CSS声明的元素就会生成BFC.

  • 根元素
  • float不为none
  • overflow不为hidden
  • display: inline-block, table-cell, table-caption(注意: 值为table会生成BFC是因为会默认生成一个匿名的table-cell,所以不是table生成了BFC)
  • position: absolute, fixed
 

BFC的约束

浏览器对BFC约束如下:

1. 生成BFC的子元素会一个接一个的放置,在垂直方向上的起点是包含块的顶部,相邻的子元素之间的垂直距离由margin控制.在BFC中相邻的块级元素外边距会折叠.
2. BFC中的子元素中,每一个子元素的左外边距与包含块的左边界接触(从右到左的格式化,与右边界接触),即使浮动元素也如此,除非这个子元素也创建了BFC.

具体展开来说就是:
1. 内部Box在垂直方向上一个接一个放置
2. 垂直方向的距离由margin决定.
3. 每个元素的左外边距与包含块的左边界接触,即使浮动元素也是如此.所以BFC中的元素不会超出包含块,但是position为absolute的元素可以超出包含块的边界.
4. BFC的区域不会与float元素的区域重合.
5. 计算BFC的高度会包含float元素,但是float元素会使父元素高度塌陷.注意区别BFC高度和父元素高度.
6. BFC相当于页面上的一个独立的容器.子元素不影响外部元素,反之亦然.
所以看到这些约束,一些常见的规则就可以了解原因.比如:

- 块级元素与父元素同宽,垂直排列
- 垂直方向上的相邻div的外边距会折叠
- 浮动元素会尽量接近左上方
- 父元素浮动,或者overflow为hidden会包住子元素
 

BFC在布局中的应用

 

1. 解决margin折叠

同一个BFC中的两个相邻Box才会发生重叠与方向无关,不过由于上文提到的第一条限制,我们甚少看到水平方向的margin重叠。这在IE中是个例外,IE可以设置write-mode

 
  1. <!doctype HTML>
  2. <html>
  3. <head>
  4. <style type="text/css">
  5. #green {
  6. margin:10px 10px 10px 10px
  7. }
  8. #blue {
  9. margin:10px 10px 10px 10px
  10. }
  11. #red {
  12. margin:10px 10px 10px 10px
  13. }
  14. body {
  15. writing-mode:vertical-rl;
  16. }
  17. </style>
  18. </head>
  19. <body>
  20. <div id="green" style="background:lightgreen;height:100px;width:100px;"></div>
  21. <div id="blue" style="background:lightblue;height:100px;width:100px;"></div>
  22. <div id="red" style="background:pink;height:100px;width:100px;"></div>
  23. </body>
  24. </html>

可以看到水平方向发生了重叠

要阻止margin重叠,只要将两个元素别放在一个BFC中即可(可以用上文提到的方式让相邻元素其中一个生成BFC)。阻止两个相邻元素的margin重叠看起来没有什么意义,主要用于嵌套元素。

 
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  5. <!--The viewport meta tag is used to improve the presentation and behavior of the samples
  6. on iOS devices-->
  7. <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no"/>
  8. <title></title>
  9. <style>
  10. html, body { height: 100%; width: 100%; margin: 0; padding: 0; }
  11. .first{
  12. margin:20px;
  13. background:lightgreen;
  14. width:100px;
  15. height:100px;
  16. }
  17. ul{
  18. /*display:inline-block;*/
  19. margin:10px;
  20. background:lightblue;
  21. }
  22. li{
  23. margin:25px;
  24. }
  25. </style>
  26. </head>
  27. <body>
  28. <div class="first"></div>
  29. <ul>
  30. <li>1</li>
  31. <li>2</li>
  32. <li>3</li>
  33. </ul>
  34. </body>
  35. </html>

此时div与ul之间的垂直距离,取div、ul、li三者之间的最大外边距。

要阻止嵌套元素的重叠,只需让ul生成BFC即可(将代码中饭的display注释去掉),这样div、ul、li之间便不会发生重叠现象。而li位于同一BFC内所以仍然存在重叠现象。

 

2. 解决浮动

在清楚浮动带来的问题的解决方案中,一定会回答用BFC清除,那到底是怎么清除的呢?根本原因就是父级元素创建BFC后,子元素即使浮动也会参与BFC高度的计算.即不会产生高度塌陷的问题.

 
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="utf-8">
  5. <title>JS Bin</title>
  6. <style>
  7. html, body {
  8. height: 100%;
  9. width: 100%;
  10. margin: 0;
  11. padding: 0;
  12. }
  13. .first{
  14. margin:20px;
  15. background:lightgreen;
  16. border: 2px solid lightgreen;
  17. /*display:inline-block;*/
  18. /*overflow:hidden;*/
  19. /*float: left;*/
  20. /*position: absolute;*/
  21. }
  22. ul{
  23. overflow:hidden;
  24. margin:10px;
  25. background:lightblue;
  26. width:100px;
  27. height:200px;
  28. float: left;
  29. }
  30. li{
  31. margin:25px;
  32. }
  33. </style>
  34. </head>
  35. <body>
  36. <div class="first">
  37. <ul>
  38. <li>1</li>
  39. <li>2</li>
  40. <li>3</li>
  41. </ul>
  42. </div>
  43. </body>
  44. </html>


将代码中first样式中任意一项注释去掉都可以得到包围浮动的效果,其中overflow:hidden方式,与正常流最接近。
关于清除浮动的详细介绍,请参考这篇简洁明了的文章.

 

3. 多栏布局的BFC实现

通过BFC约束: BFC的区域不会与float的元素区域重叠, 可以来实现多栏布局.

 
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="utf-8">
  5. <title>JS Bin</title>
  6. <style>
  7. html, body {
  8. height: 100%;
  9. width: 100%;
  10. margin: 0;
  11. padding: 0;
  12. }
  13. .left{
  14. background:pink;
  15. float: left;
  16. width:180px;
  17. }
  18. .center{
  19. background:lightyellow;
  20. overflow:hidden;
  21. }
  22. .right{
  23. background: lightblue;
  24. width:210px;
  25. float:right;
  26. }
  27. </style>
  28. </head>
  29. <body>
  30. <div class="container">
  31. <div class="left">
  32. <pre>
  33. .left{
  34. background:pink;
  35. float: left;
  36. width:180px;
  37. }
  38. </pre>
  39. </div>
  40. <div class="right">
  41. <pre>
  42. .right{
  43. background:lightblue;
  44. width:180px;
  45. float:right;
  46. }
  47. </pre>
  48. </div>
  49. <div class="center">
  50. <pre>
  51. .center{
  52. background:lightyellow;
  53. overflow:hidden;
  54. height:116px;
  55. }
  56. </pre>
  57. </div>
  58. </div>
  59. </body>
  60. </html>

这种布局的特点在于左右两栏宽度固定,中间栏可以根据浏览器宽度自适应。

 

收获

初次看到BFC这个词,是在一个面试题上.然后百度了一下,看到了寒冬大神的一篇博客,当时看完是觉得BFC,对于大佬来说是必要的,对我而言还太早.确实,当时的我还是一个连布局什么都不是很懂的菜鸟(当然现在也是).在看了一些CSS的基础之后,通过查阅资料,在这里提及一下,最新的布局方案Flex和Grid都会生成BFC,具体可以去看MDN,看一些前辈的心得,总是觉得会了,但是过段时间就忘掉了.俗话,能给别人讲明白才是真正的理解了.所以才绞尽脑汁写了这样一个总结.

其实对于BFC,我们只要知道一些特定的CSS声明会生成BFC,浏览器对BFC有一套特定的渲染规则,利用这些特殊的规则在布局上解决一些问题,就差不多了.但是当深入理解之后,会发现很多最常见的效果,就是因为BFC.当探究到这些的时候,前端的乐趣就在这里了.

文章中的内容可能有很问题,希望不吝指导.毕竟工作经验对于我还是欠缺的,遇到问题探究问题的方式方法不一样.不过话说回来,技术的乐趣就在于不断的探究,试错,总结积累上.

最后提一下IE,在IE中有类似的hasLayout.有兴趣可以研究研究.

关于BFC的一些事的更多相关文章

  1. 浅析CSS中的BFC和IFC

    1. 为什么会有BFC和IFC 首先要先了解两个概念:Box和formatting context: Box:CSS渲染的时候是以Box作为渲染的基本单位.Box的类型由元素的类型和display属性 ...

  2. CSS魔法堂:重新认识Box Model、IFC、BFC和Collapsing margins

    前言   盒子模型作为CSS基础中的基础,曾一度以为掌握了IE和W3C标准下的块级盒子模型即可,但近日在学习行级盒子模型时发现原来当初是如此幼稚可笑.本文尝试全面叙述块级.行级盒子模型的特性.作为近日 ...

  3. 重新认识Box Model、IFC、BFC和Collapsing margins

    尊重原创,转载自: http://www.cnblogs.com/fsjohnhuang/p/5259121.html 肥子John^_^ 前言   盒子模型作为CSS基础中的基础,曾一度以为掌握了I ...

  4. 盒子模型、IFC、BFC和Collapsing margins

    前言 盒子模型作为CSS基础中的基础,曾一度以为掌握了IE和W3C标准下的块级盒子模型即可,但近日在学习行级盒子模型时发现原来当初是如此幼稚可笑.本文尝试全面叙述块级.行级盒子模型的特性.作为近日学习 ...

  5. 深入理解BFC和IFC

    1. 为什么会有BFC和IFC 首先要先了解两个概念:Box和formatting context: Box:CSS渲染的时候是以Box作为渲染的基本单位.Box的类型由元素的类型和display属性 ...

  6. 前端人员不要只知道KFC,你应该了解 BFC、IFC、GFC 和 FFC

    前言 说起KFC,大家都知道是肯德基,但面试官问你什么是BFC.IFC.GFC和FFC的时候,你是否能够像回答KFC是肯德基时的迅速,又或者说后面这些你根本就没听说过,作为一名前端开发工程师,以上这些 ...

  7. 深入理解BFC

    定义 在解释BFC之前,先说一下文档流.我们常说的文档流其实分为定位流.浮动流和普通流三种.而普通流其实就是指BFC中的FC.FC是formatting context的首字母缩写,直译过来是格式化上 ...

  8. “fixed+relative==absolute”——对BFC的再次思考

    好久没写博客了,刚好今天跨年夜没约到什么妹子,在家宅着不如写点东西好了. 需求 昨天晚上,给公司年会做一个移动端的投票页面,遇到一个UI优化的问题: · 正文内容少于一屏时,投票提交按钮固定显示在页面 ...

  9. 关于CSS inline-block、BFC以及外边距合并的几个小问题

    CSS inline-block和BCF对于初学者来说,总是弄不太明白,下面记录下我在学习这块知识的过程中遇到的几个问题,供大家参考,有不足的地方,欢迎大家批评指正. 一.在什么场景下会出现外边距合并 ...

随机推荐

  1. yaml文件解析详解

    前言 yaml文件是什么?yaml文件其实也是一种配置文件类型,相比较ini,conf配置文件来说,更加的简洁,操作也更加简单,同时可以存放不同类型的数据,不会改变原有数据类型,所有的数据类型在读取时 ...

  2. js高程3--面向对象的程序设计--创建对象

    创建对象 这是js高程3--第6章面向对象的程序设计--第二节创建对象的总结与自己的理解,每一种模式都有自己的优点与缺点,搞清楚它们出现的历史原因,优缺点,我们才能使用的更加游刃有余! 本片文章并没有 ...

  3. threejs 学习之

    主要内容: 使用 threejs 创建 20x20 的网格,鼠标移动时,方块跟随移动,点击时在网格任意位置放置方块,按 shift 时,删除当前位置方块. 流程如下: 创建网格 创建一个与网格同样尺寸 ...

  4. C语言连接mysql,用GCC编译

    1. main.c文件内容如下 #include <stdlib.h>#include <stdio.h>#include <winsock.h>#include ...

  5. 行车记+翻车记:.NET Core 新车改造,C# 节能降耗,docker swarm 重回赛道

    非常抱歉,10:00~10:30 左右博客站点出现故障,给您带来麻烦了,请您谅解. 故障原因与博文中谈到的部署变更有关,但背后的问题变得非常复杂,复杂到我们都在怀疑与阿里云服务器 CPU 特性有关. ...

  6. 使用Counter进行计数统计

    使用Counter进行计数统计 想必大家对计数统计都不陌生吧!,简单的说就是统计某一项出现的次数.实际应用中很多需求都需要用到这个模型,如检测样本中某一值出现的次数.日志分析某一消息出现的频率分析文件 ...

  7. tf.nn.l2_loss()的用法

    https://blog.csdn.net/yangfengling1023/article/details/82910536

  8. 【在 Nervos CKB 上做开发】Nervos CKB 脚本编程简介[1]:验证模型

    CKB 脚本编程简介[1]: 验证模型 本文作者:Xuejie 原文链接:Introduction to CKB Script Programming 1: Validation Model 本文译者 ...

  9. 如何运用PHP+REDIS解决负载均衡后的session共享问题

    一.为什么要使用Session共享? 稍大一些的网站,通常都会有好几个服务器,每个服务器运行着不同功能的模块,使用不同的二级域名,而一个整体性强的网站,用户系统是统一的,即一套用户名.密码在整个网站的 ...

  10. rabbit - producer的confirm和consumer的ack模式

    本篇和大家分享的是关于rabbit的生产和消费方的一些实用的操作:正如文章标题,主要内容如producer的confirm和consumer的ack,这两者使用的模式都是用来保证数据完整性,防止数据丢 ...