1. 为什么会有BFC和IFC

  首先要先了解两个概念:Box和formatting context;
  Box:CSS渲染的时候是以Box作为渲染的基本单位。Box的类型由元素的类型和display属性决定,box的类型分为block-level box 和inline-level box(不包括css3的时候)。不同类型的box参与不同类型的formatting context布局。

  Block-level elements are those elements of the source document that are formatted visually as blocks (e.g., paragraphs). The following values of the 'display' property make an element block-level: 'block', 'list-item', and 'table'.

  Block-level boxes are boxes that participate in a block formatting context.

  block-level box:形式上表现为块(此处和块元素的区别主要是不包含块元素里的non-replaced inline blocks(这里一般指canvas,svg,input元素等) and non-replaced table cells)或者display 属性为 block, list-item, table 的元素,会生成 block-level box。并且参与 block fomatting context; 
  inline-level box:display 属性为 inline, inline-block, inline-table 的元素,会生成 inline-level box。并且参与 inline formatting context;
  run-in box: css3 中才有,即GFC,FFC  
  Formatting context:每个渲染区域用formatting context表示。它决定了其子元素将如何定位,以及和其他元素的关系和相互作用
       BFC和IFC则可以理解为不同渲染区域遵循的不同规则。

2. 什么是BFC和IFC

  • BFC

  1. 什么时候会产生BFC:

  1. float is not none
  2. position is absolute & fixed
  3. display is table-cell,table-caption,inline-block,flex,inline-flex
  4. overflow is not visible
  5. block-level box

  2. 特性:

o   内部的Box会在垂直方向,一个接一个地放置。
o   Box垂直方向的距离由margin决定。属于同一个BFC的两个相邻Box的margin会发生重叠每个元素的margin box的左边,与包含块border box的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此。
o   BFC的区域不会与float box重叠。
o   BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。
o   计算BFC的高度时,浮动元素也参与计算。  

  3. 作用:

    通常会用BFC来解释以下2个问题:
    1. margin collapse:上下margin会合并(这里不过多阐述,可参考链接[3])
    2. contain float: 
    其中的一种解决方法:overflow:hidden ,创建新的BFC,可以包含float元素,父元素就有高度值了

    此处阐述一下自己的理解:如果父元素只包含浮动元素,因为浮动元素是不包含在正常流的,浮动孩子将会脱离页面的常规流,因此父元素相当于不包含任何元素,高度为0。

    而BFC里面有两条规则:
    1、BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。
    2、计算BFC的高度时,浮动元素也参与计算
    overflow:hidden会产生新的BFC,子元素的被包含在父元素的BFC中,因此父元素不受子元素影响,恢复常规布局,遵循BFC规则,同时计算高度时,父元素的高度会将浮动元素算进来,因此父元素有了高度。

    不过这里要阐述一件事就是高度塌陷只出现在父元素包含且只包含浮动元素的时候:

    看图:在父元素没有明确定义height的时候,如果只包含浮动元素,父元素会出现高度塌陷的问题。(其中的解决方法主要有添加伪元素clear:both,设置父元素height,设置父元素overflow:hidden等方式)

下图:当父元素内部有非float元素时(clear:both的原理)
  
  • IFC
  IFC也是一种布局规则,inline元素和inline-block符合IFC的布局规则。在IFC布局中重点关注一下line box。
  (补充一下:IFC的生成条件是元素满足inline-level box)

在IFC中,内联元素在水平方向上一个接一个的排布,其中,容器之间水平方向上的margin,padding,border方向上是好使的。他们垂直方向上有很多种对其方式,比如居底部或顶端对齐,或者基线对齐。他们对齐完了之后形成的这个四方块儿区域,叫做一个line box(行框)。

  一个line box的宽度由包含它的元素的宽度和包含它的元素里面有没有float元素来决定,而高度由内部元素中实际高度最高的元素而计算出来。

  line box的高度是足够高来包含他内部的容器们的,也可能比它包含的容器们都高(比如在基线对齐的时候),当他包含的内部容器的高度小于line box的高度的时候,内部容器的垂直位置由自己的vertical这个属性来确定。当内部的容器盒子太多了一个line box装不下来,他们折行之后会变成两个或者多个line box, line box们相互之间垂直方向不能分离,不能重叠。

  一般来说,line box的左边缘挨着包含它的元素的左边缘,并且右边缘挨着包含它的元素的右边缘,浮动元素会在包含他们的元素的边缘和line box的边缘之间,所以虽然在同一个IFC下的line box们通常拥有相同的宽度(就是包含他们的容器的宽度),但是也会因为浮动元素的捣乱,导致line box们的可用宽度产生了变化不一样了。在同一个Ifc下的line box们的高度也会不一样(比如说,一个line box里有个比较大的image,他就高了)。

  如果一个line box 里的内联元素们的宽度总和小于这个line box的宽度,那么他们在这个line box里的水平方向的排布方式由 text-align这个属性来决定,如果这个属性被设置成了“justify”,可以使这些盒子在剩余空间内拉伸(除了inline-table 和 inline-block的元素)

  在一个line box中,当他包含的内部容器的高度小于line box的高度的时候,内部容器的垂直位置由自己的vertical这个属性来确定。那么,我们设想一下,如果手动创建一个IFC的环境,让line box的高度是包含块的高度的100%,让line box内部的元素使用vertical-align:middle,就可以实现垂直居中。

  一个line box的高度由内部元素中实际高度最高的元素而计算出来。所以,我们在line box中插入一个高度100%的inline-block元素。则会把整个line box撑高直到包含块的100%.
  当内联元素的宽度超过了line box的宽度,那么它会折行分裂成了几个line box,如果这个元素里面的内容不可以折行,例如只有一个字,或者white-space设置了nowrap/pre。那么内联元素会溢出line box。
  当一个内联元素分裂时,分裂处的 margins, borders 和 padding不会有任何视觉效果(或者其他任何分裂,只要是有多个line box)。
  line box 的生存条件是在IFC中并且包含inline-level元素,如果line box里没有文本,空白,换行符,内联元素,也没有其他的存在IFC环境中的元素,(如inline-block,inline- table,images等),将会被视为零高度,也将会被视为没有意义。
  补充:在IFC的环境中,是不能存在block-level元素的,如果将block-level元素插入到IFC中,那么此IFC将会被破坏掉, 而block-level元素前的元素和block-level元素后的元素将会各自自动产生一个匿名容器其包围,这个匿名的容器内部环境将是一个新的 IFC。

  此处补充一些自己对于IFC高度计算的理解:主要是line-height和height

  IFC中height的计算方式:line height表示高度

  *line-height如果没有显式声明,那么继承父元素的line-height;如果显示声明了,则用声明后的高度(vertical-align的时候参考的边界值)

  css中的line-height表示line space(行间差值) + font-size

看下图:

可以得到:1.height对inline元素并不起作用 2.只有设置了line-height的inline元素才会参与vertical-align的排列规则(这里个人分析是因为只有设置了高度,vertical-align时才能计算到边界值,从而对其进行排列,否则默认都是baseline规则)

此处可以再看一个例子:

 这个地方设置第二个元素的line-height是80,而父元素的line-height是100,vertical-align默认是相对于父元素的排列。首先中线的位置是一半,所以(100/2)-(80/2)=10,第二个元素下移了10px。
更多关于vertical-align的知识可以参考[6],[7]。
 
参考文献:

浅析CSS中的BFC和IFC的更多相关文章

  1. 浅析CSS里的 BFC 和 IFC

    前端日刊 登录 浅析CSS里的 BFC 和 IFC 2018-01-29 阅读 1794 收藏 3 原链:segmentfault.com 分享到:   前端必备图书<Web安全开发指南 掌握白 ...

  2. BFC?来自CSS中的BFC

    浮动元素和绝对定位元素,非块级盒子的块级容器(例如 inline-blocks, table-cells, 和 table-captions),以及overflow值不为“visiable”的块级盒子 ...

  3. 浅析 CSS 中的边距重叠

    浅析 CSS 中的边距重叠 边距重叠是什么 在说边距重叠之前,先以正常的思维来考虑如果你现在是浏览器引擎遇到这种情况应该怎么办? 现在有两个元素 div1 和 div2 紧挨着,中间没有它元素,它们的 ...

  4. CSS 中的 BFC,IFC,GFC和FFC

    原文网址:http://www.cnblogs.com/dingyufenglian/p/4845477.html What‘s FC? 一定不是KFC,FC的全称是:Formatting Conte ...

  5. CSS中的BFC

    CSS当中BFC介绍 在前端当中,我们都知道标准文档流,我们在开发的时候,经常会碰到block和inline.而下文要说到的BFC就是对块级盒子的格式化.当然block级别的盒子是BFC,那么inli ...

  6. 浅析CSS中的haslayout

    作为一名web开发人员,最大的希望不是自己的水平有多高,而是希望浏览器厂家能够统一标准,相信任何一个只要是接触过web程序开发的人员都有那样的感受,就是浏览器之间的兼容性问题总是让我们的工作平添诸多的 ...

  7. 我对CSS中的BFC的理解

       1.什么是BFC 其实在老师让我们写这篇叫BFC的时候,我跟本不知道有什么BFC的东西. 后来,我找了一些资料,知道了,BFC是Block Formatting Context (块级格式化上下 ...

  8. CSS中的BFC详解

    引言: 这篇文章是我对BFC的理解及总结,带你揭开BFC的面纱.你将会知道BFC是什么,形成BFC的条件,BFC的相关特性,以及他的实际应用. 一.何为BFC BFC(Block Formatting ...

  9. 理解CSS中的BFC(块级可视化上下文)[译]

    开篇 一些元素,如float元素,如position为absolute,inline-block,table-cell或table-caption的元素,以及overflow属性不为visible的元 ...

随机推荐

  1. 机器指令翻译成 JavaScript —— No.6 深度优化

    第一篇 中我们曾提到,JavaScript 最终还得经过浏览器来解析.因此可以把一些优化工作,交给脚本引擎来完成. 现代浏览器的优化能力确实很强,但是,运行时的优化终归是有限的.如果能在事先实现,则可 ...

  2. Mono 4.0 Mac上运行asp.net mvc 5.2.3

    Mono 4.0 已经发布,二进制包已经准备好,具体的发布说明参见:http://www.mono-project.com/docs/about-mono/releases/4.0.0/. 今天在Ma ...

  3. [DeviceOne开发]-手势动画示例分享

    一.简介 这是iOS下的效果,android下完全一致.通过do_GestureView组件和do_Animation组件,deviceone能很容易实现复杂的跨平台纯原生动画效果,这个示例就是通过手 ...

  4. ABP源码分析五:ABP初始化全过程

    ABP在初始化阶段做了哪些操作,前面的四篇文章大致描述了一下. 为个更清楚的描述其脉络,做了张流程图以辅助说明.其中每一步都涉及很多细节,难以在一张图中全部表现出来.每一步的细节(会涉及到较多接口,类 ...

  5. java调用CXF WebService接口的两种方式

    通过http://localhost:7002/card/services/HelloWorld?wsdl访问到xml如下,说明接口写对了. 2.静态调用 // 创建WebService客户端代理工厂 ...

  6. python __globals__, __file__

    Attribute Meaning   __doc__ The function's documentationstring, or None ifunavailable; not inherited ...

  7. 06. Web大前端时代之:HTML5+CSS3入门系列~HTML5 画布

    Web大前端时代之:HTML5+CSS3入门系列:http://www.cnblogs.com/dunitian/p/5121725.html 我们先看看画布的魅力: 初始画布 canvas默认是宽3 ...

  8. 编写Windows服务疑问1:操作过程

    Windows 服务开发平时不太受人关注,毕竟那是高大上的项目类型,平常需求也用不上,很多老掉牙的家伙也只知有WinForm,仍不知有WPF,更别说Windows 服务了,正如陶渊明所写的,“不知有汉 ...

  9. SQL Server-聚焦LEFT JOIN...IS NULL AND NOT EXISTS性能分析(十七)

    前言 本节我们来分析LEFT JOIN和NOT EXISTS,简短的内容,深入的理解,Always to review the basics. LEFT JOIN...IS NULL和NOT EXIS ...

  10. three.js笔记

    /*** 场景(scene) ***/ var scene = new THREE.Scene(); // 创建场景 scene.add(x); // 插入场景 /*** 相机(camera) *** ...