lazysheep 10 X 10
Last updated: 2017-05-07
lazysheep:~ Desktop$ node 来聊一聊BFC.js

> Post.tags
BFCCSS布局

> Post.prev
node菜鸟笔记(1)---Mongodb+express实现简单登陆注册

> Post.next
Hello
来聊一聊BFC

前几天看了看张鑫旭大大的一篇关于浮动的视频,其中提到了BFC(当时并未在意),后面自己遇到了一个collapsed margin的问题于是就去看看了BFC,下面就来记录记录BFC以及其的一些应用~

遇到的问题

给子元素设置了margin-top margin-bottom后 父元素也会相应的类似于添加了margin-top跟margin-bottom但是根元素并不受影响:
father
html

外边距折叠(collapsed margin)

两个或多个相邻(父子元素或兄弟元素)的块级框垂直方向上的 margin 会发生折叠。这种方式形成的外边距即可称为外边距折叠(collapsed margin)。
其中折叠的计算方法为,如果两者的外边距都为正值,则折叠后的外边距值为两者的较大值;如果其中有一个是负值,则折叠后的外边距值为正值减去负值的绝对值得到的值;如果两者都是负值,则折叠后的外边距值为用0减去两者的绝对值中较大的那一个。

这就是为什么会出现以上父元素的外边距会被子元素的外边距影响的原因啦至于为什么根元素为什么没被影响,请继续看下面

BFC(Block Formatting Context)

BFC是Block Formatting Context的缩写,译为块级格式上下文

  • 创建了BFC的元素规定了内部的块级框如何布局,并且使该框在页面上形成一个隔离的独立容器,容器里面的子元素不会影响到外面的元素
  • 在BFC中,框会从包含块的顶部开始,一个接一个地,垂直向下地摆放
  • 两个兄弟框之间的垂直距离由margin属性来决定。在同一个BFC中,相邻的块级框之间的垂直外边距会出现折叠(常见的外边距折叠,其实并不是bug,而是由于BFC的约束)
  • 在BFC中,每个框的左外边距边要紧贴其包含块的左边(对于从左往右的格式化),否则相反。即使在有浮动的情景下也是如此,除非框创建了一个新的BFC(在这种情况下该框可能会为了避开浮动框而变窄)
  • BFC的区域不会与float box重叠
  • 计算BFC的高度时,浮动元素也参与计算(overflow:hidden 可以清除浮动)
  • 下列情况将创建一个BFC:
    • 根元素(由于html标签是根元素是一个BFC所以就不会被子元素影响啦)
    • 浮动 (元素的 float 不为 none)
    • 绝对定位元素 (元素的 position 为 absolute 或 fixed)
    • 行内块 inline-blocks (元素的 display: inline-block)
    • 表格单元格 (元素的 display: table-cell,HTML表格单元格默认属性)
    • 表格标题 (元素的 display: table-caption, HTML表格标题默认属性)
    • overflow 的值不为 visible的元素
    • 弹性盒子 flex boxes (元素的 display: flex 或 inline-flex)

BFC 应用

最常见的就是防止外边距折叠啦~

1. 防止外边距折叠

demo1

demo2

demo3

Oh!折叠了 QAQ

两个兄弟框之间的垂直距离由margin属性来决定。在同一个BFC中,相邻的块级框之间的垂直外边距会出现折叠。

那么我们只需让他们不在同一个BFC中就可以防止折叠了。比如说给第一个p或第2个p加float、给第一个p或第2个p外面包裹一层容器,并触发该容器生成一个BFC。

2. 清除浮动

正如前面所说只需要给父级元素添加一个overflow: hidden 就好啦~ 因为计算BFC的高度时,浮动元素也参与计算
demo4

demo5

3. 自适应三列布局

demo6

demo7

demo8

参考

理解CSS中的BFC