写在前面:本文是我在看了CSS:潜藏着的BFC、为什么这么多人讲不清楚 BFC两篇文章后做做出的关于CSS的总结,如有错误与不足,欢迎指正,不胜感激!
Blog地址:浅谈BFC,欢迎来逛
一、什么是BFC(Block Formatting Context)
我们先来看BFC的定义:块级格式化上下文,指一个独立的块级渲染区域,该区域有一套渲染规则来约束块级盒子布局,浮动层元素可再次进行交互,且与区域外部无关。
那么BFC是如何产生的呢?查阅MDN可以看到,满足下列条件之一便会生成BFC:
- 根元素或其它包含它的元素
- 浮动元素 (元素的 float 不是 none)
- 绝对定位元素 (元素的 position 为 absolute 或 fixed)
- 内联块 (元素具有 display: inline-block)
- 表格单元格 (元素具有 display: table-cell,HTML表格单元格默认属性)
- 表格标题 (元素具有 display: table-caption, HTML表格标题默认属性)
- 具有overflow 且值不是 visible 的块元素,一般默认为visible
- display: flow-root
- column-span: all 应当总是会创建一个新的格式化上下文,即便具有 column-span: all 的元素并不被包裹在一个多列容器中。
最好的方法应该是使用display:flow-root ,不过部分浏览器不支持。
二、BFC内部的渲染布局规则及功能
简单归纳如下:
1.内部元素会在垂直方向一个接一个地排列
2.垂直方向上,两相邻盒子的margin会发生合并
举一个简单的例子:
.father{
border: 1px solid;
min-height: 100px;
display: flow-root;
}
.son{
border: 1px solid red;
background-color: red;
height: 10px;
margin: 10px 0px;
}
首先创建一个父块,里面包含两个相同的子块,子块的margin设置为 10px 0px;那么理论上这两个子块中间的margin应该为10+10=20px,结果却只有10px;
当我们把下方的子块margin变为20px 0px时,理论上中的margin应该为10+20=30px;结果却只有20px;
.father{
border: 1px solid;
min-height: 100px;
display: flow-root;
}
.son{
border: 1px solid red;
background-color: red;
height: 10px;
margin: 10px 0px;
}
.son1{
border: 1px solid red;
background-color: red;
height: 10px;
margin: 20px 0px;
}
造成这种现象的原因就是margin合并:
块的顶部外边距和底部外边距有时被组合(折叠)为单个外边距,其大小是组合到其中的最大外边距,这种行为称为外边距塌陷(margin collapsing),有的地方翻译为外边距合并。
通俗地来说,BFC内相邻两元素的margin会发生合并,并且合并为两者中较大的那一个。
但是在不同的BFC中的两个元素不会发生重叠,我们甚至可以用这一特性在日常页面中防止margin合并,如:
<div class="father">
<div class="son"></div>
<div style="overflow:hidden;">
<div class="son"></div>
</div>
</div>
.son{
border:1px solid red;
margin : 10px 0px;
min-height:10px;
background-color: red;
}
此时这两个son块不会发生margin重叠:
3.BFC只管着直系子元素,直系子元素所管理的元素则管不到
让我想起了以前历史课上学的一句话“你的附庸的附庸不是你的附庸”,是什么意思呢,就是你的爸爸管着你,你的爷爷管着你的爸爸,但是你的爷爷不会管你,因为你的爸爸已经管着你了。
4.BFC中的子元素(包括浮动元素)不会超出BFC的范围
衍生功能:用 BFC 包住浮动元素
参照饥人谷方老师的代码:http://js.jirengu.com/rozaxufetu/1/edit?html,css,output
BFC有清除浮动的效果,但是不推荐这样清除浮动,因为会带来内部元素无法出父元素的副作用,清除浮动还是用.clearfix比较好。
5.BFC内部东西与外部不重合,可以用于不同组件间划清界限
衍生功能:用 float + div 做左右自适应布局,避免了侵占浮动元素
参照饥人谷方老师的代码:http://js.jirengu.com/felikenuve/1/edit?html,css,output