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]。
 
参考文献:

深入理解BFC和IFC的更多相关文章

  1. 重拾 BFC、IFC、GFC、FFC

    温故知新,巩固基础 从 FC 开始 FC,Formatting Context,格式化上下文,是 W3C CSS2.1 规范中的一个概念,定义的是页面中一块渲染区域,并且有一套渲染规则,它决定了其子元 ...

  2. 浅析CSS中的BFC和IFC

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

  3. 全面理解BFC

    BFC 已经是一个耳听熟闻的词语了,网上有许多关于 BFC 的文章,介绍了如何触发 BFC 以及 BFC 的一些用处(如清浮动,防止 margin 重叠等).虽然我知道如何利用 BFC 解决这些问题, ...

  4. 理解 BFC

    BFC 已经是一个耳听熟闻的词语了,网上有许多关于 BFC 的文章, 介绍了如何触发 BFC 以及 BFC 的一些用处(如清浮动,防止 margin 重叠等). 虽然我知道如何利用 BFC 解决这些问 ...

  5. CSS的两种格式化上下文:BFC和IFC

    CSS的两种格式化上下文   文章包含很多个人理解,如果错误,欢迎指出~   在看本文之前,你要对CSS的盒子模型,Block-Level元素,Inline-Level元素有所了解,具体可参考CSS的 ...

  6. 浅析CSS里的 BFC 和 IFC

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

  7. 深入理解BFC

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

  8. BFC与IFC

    在我们做的网页上通常最重要的其中一点就是美观度,bfc他是一个块级格式化上下文,它是一个独立的渲染区域,只有Block-level box参与, 它规定了内部的Block-level Box如何布局, ...

  9. 深入理解BFC和Margin Collapse

    深入理解BFC和Margin Collapse   BFC的理解与应用 首先我们来看看w3c规范对BFC的解释,其实对于这种概念的学习上,我们总是建议首先寻找官方的定义,因为原则上来说官方的才是最权威 ...

随机推荐

  1. 分享一个linux中测试网站是否正常的shell脚本

    #! /bin/bash #Author=Harry CheckUrl() { #<==定义函数,名字为CheckUrl timeout=5 #<==定义wget访问的超时时间,超时就退出 ...

  2. new 和 malloc 的区别 及使用

    Malloc: 定义上:malloc  memory allocation 动态内存分配 是c中的一个函数 使用方法: extern void *malloc(unsigned int num_byt ...

  3. CentOS7中MySQL跨机器数据迁移

    1.概况 在CentOS7环境下,使用命令方式将MySQL数据从源端主机迁移到目标端主机上. 2.迁移全部数据库 1)源端备份: [root@hadoop102 /]# mysqldump -u ro ...

  4. faker数据填充详解

    安装 在laravel中已经自动集成,无需手动安装.如需在其他地方使用,可使用以下命令进行安装. composer require fzaninotto/faker 为Faker指定中文支持 可通过在 ...

  5. tensorflow学习笔记五----------逻辑回归

    在逻辑回归中使用mnist数据集.导入相应的包以及数据集. import numpy as np import tensorflow as tf import matplotlib.pyplot as ...

  6. [LeetCode] 103. 二叉树的锯齿形层次遍历

    题目链接 : https://leetcode-cn.com/problems/binary-tree-zigzag-level-order-traversal/ 题目描述: 给定一个二叉树,返回其节 ...

  7. win10无法开启网络发现怎么办 如何启用网络发现

    鼠标右键点击桌面左下角的开始按钮,在弹出的菜单中选择“运行”菜单项.   在打开的Windows10运行窗口中,输入Services.msc,然后点击确定按钮.   在打开的Windows10服务窗口 ...

  8. Windows消息理解(系统消息队列,进程消息队列,非队列消息)

    // ====================Windows消息分类==========================在Windows中,消息分为以下三类:标准消息——除WM_COMMAND之外,所 ...

  9. linux:服务器代理squid安装配置

    国内上往外的网站太慢,配了个香港代理服务器.如下:当前环境: centos系统.香港服务器IP(假设:59.188.71.11)检查squid是否安装:[root@localhost ~]# rpm ...

  10. 吴恩达深度学习:2.3梯度下降Gradient Descent

    1.用梯度下降算法来训练或者学习训练集上的参数w和b,如下所示,第一行是logistic回归算法,第二行是成本函数J,它被定义为1/m的损失函数之和,损失函数可以衡量你的算法的效果,每一个训练样例都输 ...