BFC深入理解
BFC
在上一篇文章中,清除浮动方法解析,我们谈及了一些使用css属性解决浮动带来的影响。但是在解决浮动带来的影响的方法中,如果细心思考,会产生如下疑问:
- 为什么
overflow
可以清除浮动带来的影响? - 能否用其他css属性清除浮动带来的影响?
种种的疑问,会让你觉得CSS真的不容易精通,说精通过于高大上,就连掌握都挺难的。
在清除浮动方法解析文章中,只是稍微说明了一下上面两个问题的原因是BFC(块级格式化上下文,Block Formatting Contexts)。在分享BFC之前,有必要谈谈另外一个概念。也就是可视化格式模型
可视化格式模型
我们知道,CSS元素可分为两种,块级元素和行内元素。块级元素显示为块内容,对应着CSS元素框的‘块框’。行内元素显示在一行中,对应着CSS元素框的‘行内框’。
块框在DOM中从上到下一个接一个地垂直排列,每一个块框之间地垂直距离由框的垂直外边距决定。如果在某个div内定义了一段纯文本,此时这段纯文本会被包含在匿名块框内。
行内框在DOM中从左到右一个接一个地水平排列,由一行形成的水平框称为行框,行框的高度总是足以容纳它包含的所有行内框。行内框(行内元素)可以通过水平padding
、border
、margin
来改变两两行内框的水平间距。但是,垂直border
、padding
、margin
不影响两两行内框的垂直间距,同时垂直方向不占据任何空间。如果想要改变行内框(行内元素)的高度,可以使用line-height
来改变。
line-heignt主要用于控制行框的高度。
看个图示。上为水平,下为垂直。
水平距离改变,垂直border不占据空间,因此挡住了文字。
W3school中指出,display
属性可以规定某个元素生成框的类型。比如说,将某个行内元素设置display:block
,此时,行内元素对应的行内框因为display属性的影响,行内框变成了块框,即行内元素可以拥有像块级元素一样的特性。
BFC(Block Formatting Context,块级格式化上下文)
知道可视化格式模型之后,我们来谈谈BFC。
我理解的BFC,其实就像一个隐藏技能,这种隐藏的技能是被动的,需要通过其他技能的使用才能发挥它的作用。在CSS中,BFC其实就是一个隐藏属性,这种隐藏属性需要其他特定的CSS属性定义之后才会被触发。当触发了BFC这个隐藏属性之后,就可以解决一系列的问题。
从可视化格式模型上来说,每一个块框都可以看成是一个拥有隐藏的BFC属性,在DOM中从上到下垂直排列,块框之间的距离由外边距决定。
普通文档流的父级块框就是自带隐藏BFC属性的,不同的块框可能会在内部产生块级格式化上下文。
触发BFC的条件:
- 父级块框自带隐藏BFC属性
- 浮动元素
- 绝对定位元素(包括
absolute
和fixed
) - 框类型
display
为:inline-block|table-cell|table-caption
overflow
属性为hidden|auto|scroll
BFC可以解决的问题:
1.(BFC与margin)同一个父级块框下,兄弟元素和父子元素的margin会发生重叠问题
2.(BFC与float)父元素高度塌陷问题、兄弟元素覆盖问题
BFC与margin
margin重叠的解决方法:让元素处于不同的BFC属性环境下。
兄弟元素
在同一个父级块框下,兄弟元素和父子元素的margin会发生重叠,并且这种重叠会遵循一定得规则:同号取大,异号相加。具体可以看看关于margin的介绍。传送门:CSS margin
兄弟元素的margin重叠的解决方法:任一个兄弟元素的属性设置如下:
float:left|right
或者position:absolute|fixed
或者display:inline-block|table-cell|table-caption
父子元素
父子元素的margin重叠解决方法:父元素设置以下任意属性:overflow:hidden|auto|scroll
,或者给父元素设置padding
或border
属性。
如果元素没有垂直border
或者padding
,那么父元素的高度就是它包含的子元素的顶部和底部边框边缘之间的距离。因此,包含的子元素的顶部和底部外边距就突出到容器元素的外边。因此,可以通过添加垂直border
或者padding
,外边距就不会叠加了,而且父元素的高度就是它包含的子元素的顶部和底部外边距边缘之间的距离。
.father {
backgrund:blue;
width:500px;
height:50px;
margin-top:15px;
overflow:hidden; //padding:1px; //border:1px solid green;
}
.child {
height:30px;
width:500px;
background:pink;
margin-top:15px;
}
BFC与浮动
兄弟元素
在两个兄弟元素a和b中,如果a元素设置了float属性,b元素的布局会受到影响,此时a元素会覆盖在b元素上,如果b元素存在文字,那么文字会环绕a元素显示。
<div class="float"></div>
<div class="clearfloat">
没有设置overflow:hidden|auto|scroll;没有设置overflow:hidden|auto|scroll;没有设置overflow:hidden|auto|scroll;
</div>
<div class="float"></div>
<div class="clearfloat">
设置overflow:hidden|auto|scroll设置overflow:hidden|auto|scroll设置overflow:hidden|auto|scroll空空空空补充内容
</div>
使其中一个兄弟元素触发BFC之后就不会被其浮动元素覆盖,使用这种float+overflow的方式可以实现一侧固定,一侧自适应的布局效果。
父子元素
BFC与浮动如果针对父子元素,当然是解决父元素高度塌陷的问题了。
在W3C中指出 'Auto' heights for block formatting context roots。
也就是BFC会根据子元素的情况自动适应高度,即使其子元素中包括浮动元素。
给父元素设置以下任意属性,触发BFC隐藏属性: overflow:hidden|auto|scroll
、 position:absolute
、float:left|right
、display:inline-block
父元素触发BFC隐藏属性前
父元素触发BFC隐藏属性后