BFC(block formatting context,中文翻译为块级格式化上下文)是W3C CSS2.1规范中的一个概念,它会决定元素如何对其内容进行定位,以及与其它元素的关系和相互作用。
在进行盒子元素布局的时候,BFC提供了一个环境,在这个环境中按照一定规则进行布局不会影响到其它环境中的布局。比如浮动元素会形成BFC,浮动元素内部子元素的主要受该浮动元素影响,两个浮动元素之间是互不影响的。
也就是说,如果一个元素符合了成为BFC的条件,该元素内部元素的布局和定位就和外部元素互不影响(除非内部的盒子建立了新的BFC),是一个隔离了的独立容器。在CSS3中,BFC叫做Flow Root。
一、形成BFC的条件(符合以下任一条件即可):
1)float的值不为none;
2)overflow的值不为visible;
3)display的值为table-cell、table-caption和inline-block之一;
4)position的值不为static或relative中的任何一个;
二、BFC常见作用
1)包含浮动元素
BFC会根据子元素的情况自适应高度,这个特性是对父元素使用overflow:hidden/auto/scroll、float:left/right样式可以闭合浮动的原理。
此外网上有资料说使用display:table可以隐式触发table-cell/table-caption,来创建BFC。
code如下:
<head>
<meta charset="utf-8" />
<style type="text/css">
.bfc-box {
width: 300px;
border: 1px solid #0000ff;
overflow: hidden;
}
.left, .right {
width: 50%;
float: left;
}
.red {
background: #cc0000;
}
.yellow {
background: #00cc00;
}
</style>
</head>
<body>
<div class="bfc-box">
<div class="left red">父元素是BFC</div>
<div class="right yellow">父元素是BFC</div>
</div>
</body>
展现图:
上面的例子中,有两个浮动div,外层父节点没有出现“高度塌陷”,这是因为
我们给父节点使用overflow:hidden创建了BFC,可以包含浮动元素,因此能正常表现出高度,其边框位置也正常。
注:此方法只能在支持BFC的浏览器(IE8+、firefox、chrome、safari)通过创建新的BFC闭合浮动;在不支持BFC的浏览器(IE6、7),则通过触发hasLayout闭合浮动。
2)不被浮动元素覆盖
浮动元素会无视兄弟元素的存在,覆盖在兄弟元素的上面,为该兄弟元素创建BFC后可以阻止这种情况的出现,如下示例
code:
<head>
<meta charset="utf-8" />
<style type="text/css">
.bfc-left {
width: 150px;
height: 50px;
background: #ffff00;
float: left;
}
.bfc-auto {
width: 200px;
height: 80px;
background: #a0c484;
color: #ffffff;
display: inline-block;
}
</style>
</head>
<body>
<div class="bfc-left">我是浮动元素</div>
<div class="bfc-auto">我是非浮动元素,创建了BFC</div>
</div>
</body>
效果图:
右侧的非浮动元素通过display:inline-block创建了BFC,则浮动的兄弟元素就不覆盖在该元素上面。这种情况仅仅是元素宽度之和没有超出父元素宽度的情况,假设浮动元素宽度和它的非浮动兄弟元素宽度都超过了父元素的宽度,非浮动元素会下降到下一行,即处于浮动元素下方,如下所示:
解决方案是外层父节点可以采用white-space:nowrap;
3)阻止父子元素的margin折叠
在知道margin外边据叠加规则之后,仅当两个块级元素毗邻并且在同一个块级格式化上下文时,它们垂直方向之间的外边距才会叠加。也就是说,即便两个块级元素相邻,但当它们不在同一个块级格式化上下文时它们的边距也不会叠加。
code:
<head>
<meta charset="utf-8" />
<style type="text/css">
.bfc-parent {
width: 300px;
background: #00ff00;
margin-top: 20px;
overflow: auto;
}
.bfc-child {
margin-top: 20px;
}
</style>
</head>
<body>
<div class="bfc-parent">
<div class="bfc-child">我是子节点,我的上外边距是20px,父级元素是BFC</div>
</div>
</body>
页面展现图:
上述div元素都有顶部外边距,但child并没有与parent顶部外边距折叠,因为parent创建了新的BFC。
以上代码在IE8、IE10和chrome测试通过,了解IE6-7的兼容解决方法,采用hasLayout。