理解BFC(二)
在上一篇文章理解BFC(一)中,我们学习了什么是BFC,即BFC会有什么样的行为。今天我们来说说BFC有什么用以及什么时候会创建BFC。
BFC的作用
防止margin折叠
下面是一个margin折叠的例子:
<style> |
我们可以看到,在inner
设置了margin之后,水平方向上明显产生了50px的margin,但是垂直方向上却不是很明显。这是因为container
和inner
属于同一个BFC,他们的margin在垂直方向上发生了折叠。也就是说,inner
的50px的margin被加到了container
上,他们两个共享50px的margin。
我们再来看看下面这个例子:
<style> |
我们可以看到,现在inner
像我们期望的那样,垂直方向上也产生了50px的margin。这是因为我们使用display: flow-root
在container2
上创建了一个新的BFC(至于为什么这样能创建BFC,后面再说),使得inner
和container
处于不同的BFC。处于不同BFC的元素不会发生margin折叠。
这里我们应该思考一下,是inner
处于新创建的BFC上还是container
处于新创建的BFC上呢?答案是inner
处于新的BFC上。
我们来看看下面这个例子:
<style> |
这次我们不在container
上创建BFC了,而是在inner上创建BFC。可以看到,margin还是发生了折叠。这是为什么呢?我们不是在inner上创建了新的BFC嘛?按道理container
和inner
处于不同的BFC才对?
然而container
和inner
还是属于同一个BFC。这是因为,我们在inner
上创建BFC,其实是改变了inner
内部的BFC,而inner
所处的BFC并没有发生改变。在上个例子中,我们在container
上创建了BFC,使得inner
处于新的BFC中,但是container
还是原来的BFC。因此他们属于不同的BFC,能够防止margin折叠。
撑开float
首先,我们要知道,float只发生在一个BFC的内部。也就是说,一个BFC内部的float元素不会影响到BFC外面的元素,它只会在这个BFC内部作妖。
来看下面这个例子:
<style> |
我们可以看到,在这个例子中,float
元素没能把 container
撑开。这是因为float元素脱离了文档流。同时,现在float元素位于<html>
标签产生的BFC中,因此会影响到这个BFC中的所有元素。
要想把container高度撑开,只需要让container生成一个BFC:
<style> |
此时,container生成了一个BFC,而float元素位于这个BFC内部,因此浏览器不允许float影响到BFC外部的元素,就会将container撑开,以便容纳下float元素。
如何生成BFC
1. <html>
根元素
<html>
根元素是最初始的一个BFC。
2. float元素
所有float为left或right的元素都会生成一个BFC。
3. 绝对定位元素
包括position:absolute
、 position:fixed
、position:sticky
。
2、3两点总结起来就是,所有脱离文档流的元素都会产生BFC。
4. display: inline-block
5. display: table-cell
6. display: tabel-caption
4-6点总结起来就是所有不是display:block的“块级元素”
7. overflow
所有设置了overflow不为visible的元素
8. display: flow-root
直接指定创建一个BFC,没有其他任何副作用。