简介
BFC(Block Formatting Context)即块级格式化上下文,它既不是一个CSS属性,也不是一段代码,而是CSS2.1规范中的一个概念,决定元素的内容如何渲染以及与其它元素的关系的交互。
可以将BFC想象成一个箱子,BFC的内容就相当于箱子中的物品,将物品摆在箱子里,能避免与其他箱子中的物品混淆,还能保护它们不被破坏。
BFC的5条规则
- BFC有隔离作用,内部元素不会受外部元素的影响(反之亦然)
- 一个元素只能存在于一个BFC中,如果能同时存在于两个BFC中,就违反了BFC的隔离规则
- BFC内的元素按正常流排列,元素之间的间隙由元素的外边距(margin)控制
- BFC中的内容不会与外面的浮动元素重叠
- 计算BFC的高度,需要包括BFC内的浮动子元素的高度
创建BFC需满足的条件
- 根元素,也就是html元素
- float属性不为none的浮动元素
- position属性是absolute或fixed的定位元素
- display属性为inline-block、table-cell(相当于td或th元素)、table-caption(相当于caption元素)或伸缩盒(flex和inline-flex)的元素
- overflow属性不为visible的块级元素
如果要创建BFC,必须满足以上条件中的一个
BFC的用途
BFC的常规用途有三个:清除浮动、解决外边距塌陷和宽度自适应的两栏布局
清除浮动
例1: 当一个元素被定义为浮动之后,附近的文件,即使不是相邻的关系,也会环绕着它。
<style type="text/css">
ul {
overflow: hidden; /**创建BFC**/
}
</style>
<ul>
<li style="float: left;background-color: aliceblue;">第一个元素</li>
</ul>
<span>外部文字</span>
让li的父级元素ul创建BFC后(例如给ul的css属性overflow定义为hidden),由于BFC有隔离作用,就能防止外部的文字环绕。
例2: 浮动的元素会脱离正常的文档流,如果附近有其他元素,并且这个元素在正常流中,将会与其重叠。
<style type="text/css">
span {
float: left;
background-color: aliceblue;
}
div {
width: 150px;
height: 60px;
background-color: antiquewhite;
overflow: hidden; /**创建BFC**/
}
</style>
例3: 如果一个元素未定义高度,并且有浮动的子元素,那么将会引起元素的高度的塌陷(height collapsing)
<style type="text/css">
ul {
background-color: aliceblue;
overflow: hidden; /**创建BFC**/
}
ul li {
width: 100px;
height: 20px;
background-color: antiquewhite;
}
</style>
<ul>
<li style="float: left;">第一个元素</li>
</ul>
解决外边距塌陷
关于外边距塌陷的几种情况可参考这篇
以父元素和子元素之间的塌陷为例:
<style type="text/css">
.wrapper {
width: 100px;
height: 100px;
background-color: aliceblue;
}
.inner-wrapper {
overflow: hidden; /**创建BFC**/
width: 100px;
height: 100px;
background-color: antiquewhite;
}
p {
width:50px;
background-color: aqua;
}
</style>
<div class="wrapper"></div>
<div style="margin-top: 10px;" class="inner-wrapper">
<p style="margin-top: 10px">p元素内容</p>
</div>
宽度自适应两栏布局
要求:左边固定,右边自适应
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>宽度自适应两栏布局</title>
<style type="text/css">
*{margin: 0; padding: 0;}
.left {
float: left;
width: 100px;
height: 100px;
background-color: aliceblue;
}
.right {
overflow: hidden;
height: 100px;
background-color: antiquewhite;
}
</style>
</head>
<body>
<div>
<div class="left">左边固定</div>
<div class="right">
右边自适应
</div>
</div>
</body>
</html>