BFC、IFC详解
盒模型
在讲BFC、IFC之前,首先来了解一下盒模型。
盒模型的结构
盒模型由以下4个部分组成:
内容content + 内边距padding + 边框border + 外边距margin
盒模型的类型
盒模型分为两类:
一是标准盒模型,其组成为 margin + border + padding + content,如下图:
二是IE盒模型,其组成为 margin + content (border + padding)
而盒模型的类型可以通过【box-sizing】属性来进行控制。
这两种盒模型的区别在于:
- 对于标准盒模型而言,从图中其实就能看到,如果向元素中添加 padding、border、margin,其会影响元素的宽高。
- 而对于IE盒模型,添加 padding、border、margin 则不会影响元素的宽高。
元素宽高变化,则意味着可能会影响其它元素的布局!
在浏览器控制台中执行以下命令,就可以看到页面中的 box 区块(红色线框部分)
[].forEach.call(document.querySelectorAll('*'), function(a){a.style.outline = "1px solid red";})
BFC、IFC
BFC
BFC(Block Formatting Context),即块级格式化上下文。
IFC(Inline Formatting Context),即行内格式化上下文。
我们先来讲 BFC,实际上理解 BFC 之后,自然也就理解 IFC 了。
BFC是W3C CSS 2.1 规范中的一个概念,它决定了元素如何对其内容进行定位,以及与其他元素的关系和相互作用。当涉及到可视化布局的时候,Block Formatting Context 提供了一个环境,HTML元素在这个环境中按照一定规则进行布局。在官方文档中,是这样介绍BFC的:
一个BFC区域包含创建该上下文元素的所有子元素,但是不包括创建了新的BFC的子元素的内部元素,BFC是一块独立的渲染区域,可以将BFC看成是元素的一种属性,拥有了这种属性的元素就会使他的子元素与世隔绝,不会影响到外部其他元素
因此,实际上可以将 BFC 视作一个箱子,箱子里面的元素不会与箱子外面的元素产生作用。
同时,可以总结出 BFC 的两个特点:
- 每一个BFC区域中,只包含该元素的子元素,而其子元素的子元素则不在其中。
- 每一个 BFC 区域,都是独立的,互相之间不会产生影响。
如何创建 BFC
- 根元素body本身就是个BFC;
- 元素设置浮动
- 元素设置绝对定位
- display 设置为inline-block、table-cell、flex等;
- overflow 设置为hidden
BFC 的应用
1.解决外边距塌陷问题(即垂直方向上的塌陷)
BFC可以用于解决开发过程中,外边距在垂直方向上的塌陷问题。看下面这个例子:
这两个盒子,都拥有 100 的外边距,但实际上两个盒子在垂直方向上的距离只有 100(本来应该是 200),这就是外边距塌陷。
那么如何使用 BFC 来解决这一问题呢?
只需要给这两个盒子都加一个父元素,并且将这个父元素设置成BFC区域,就可以解决这个margin塌陷的问题。
2.解决包含塌陷
有时候,给子元素加上 margin 时,会使得父元素位置也发生移动。例如下面这个例子:
很显然,我们只是想要子元素距离父元素50px,而不是整个父元素都一起跑。这个时候用padding可以解决问题,但是用BFC同样可以解决。
只需要将父元素变为BFC区域,就能得到解决
因为此时父元素是一个独立的区域,其中的任何操作,都不会影响到外部。
3.清除浮动
众所周知,将子元素设置浮动可能会导致父元素高度塌陷,因此需要清除浮动,即:overflow: hidden。而实际上这里就是创建了一个 BFC,从而使得子元素的变动不会影响到外部元素。
4.阻止标准流元素被浮动元素覆盖
大家都知道,浮动的元素会脱离文档流,跑到上一个层面,也就是和原本的元素们不在一个层面了。所以可能会出现浮动元素覆盖基本元素的问题。看下面这个例子:
红色元素浮动后,脱离了文档流,因此盖住了蓝色元素。那么此时,我们只需要让蓝色区域成为 BFC,即可做到不受浮动元素的影响。
而且还能利用这个特性,来实现蓝色盒子宽度根据红色盒子的宽度来做自动适应,即左边固定、右边自适应的两栏布局!