BFC:块级格式化上下文
一个BFC包含创建该上下文元素的所有子元素,但不包括创建了新BFC的子元素的内部元素。
BFC的最显著的效果就是建立一个隔离的空间,断绝空间内外元素间相互的作用。
触发BFC的条件
- 根元素或其它包含它的元素
- 浮动元素 (元素的 float 不是 none)
- 绝对定位元素 (元素具有 position 为 absolute 或 fixed)
- 内联块 (元素具有 display: inline-block)
- 表格单元格 (元素具有 display: table-cell,HTML表格单元格默认属性)
- 表格标题 (元素具有 display: table-caption, HTML表格标题默认属性)
- 具有overflow 且值不是 visible 的块元素
- 弹性盒(flex或inline-flex)
- display: flow-root
- column-span: all
BFC的约束规则
- 内部的盒会在垂直方向一个接一个排列(可以看作BFC中有一个的常规流)
- 垂直方向上的距离由margin决定。(完整的说法是:属于同一个BFC的两个相邻Box的margin会发生重叠(塌陷),与方向无关。)
- 每个元素的margin box的左边,与容器块border box的左边相接触(对于从左往右的格式化,否则相反),即使存在浮动也是如此(这说明BFC中子元素不会超出他的包含块,而position为absolute的元素可以超出他的包含块边界)
- BFC的区域不会与float的元素区域重叠
- 计算BFC的高度时,考虑BFC所包含的所有元素,连浮动元素也参与计算
- BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面元素,反之亦然
看到以上的几条约束,想想我们学习css时的几条规则
- Block元素会扩展到与父元素同宽,所以block元素会垂直排列
- 垂直方向上的两个相邻DIV的margin会重叠,而水平方向不会(此规则并不完全正确)
- 浮动元素会尽量接近往左上方(或右上方)
- 为父元素设置overflow:hidden或浮动父元素,则会包含浮动元素
BFC可以解决的问题
- 垂直外边距重叠问题
<style>
.wrap {
overflow: hidden;// 新的BFC
}
p {
color: #f55;
background: #fcc;
width: 200px;
line-height: 100px;
text-align:center;
margin: 100px;
}
</style>
<body>
<p>Haha</p>
<div class="wrap">
<p>Hehe</p>
</div>
</body>
- 去除浮动
<style>
.par {
border: 5px solid #fcc;
width: 300px;
overflow: hidden; //BFC
}
.child {
border: 5px solid #f66;
width:100px;
height: 100px;
float: left;
}
</style>
<body>
<div class="par">
<div class="child"></div>
<div class="child"></div>
</div>
</body>
- 自适用两列布局(float + overflow)
<style>
body {
width: 300px;
position: relative;
}
.aside {
width: 100px;
height: 150px;
float: left;
background: #f66;
}
.main {
height: 200px;
background: #fcc;
overflow: hidden; //BFC,BFC的区域不会与float元素重叠,否则会重叠,所以加它,变成BFC
}
</style>
<body>
<div class="aside"></div>
<div class="main"></div>
</body>
<style>
html, body { height: 100%; width: 100%; margin: 0; padding: 0; }
.left{
background:pink;
float: left;
width:180px;
}
.center{
background:lightyellow;
overflow:hidden;
}
.right{
background: lightblue;
width:180px;
float:right;
}
</style>
</head>
<body class="claro">
<div class="container">
<div class="left">
左边
<pre>
.left{
background:pink;
float: left; //BFC
width:180px;
}
</pre>
</div>
<div class="right">
右边
<pre>
.right{
background:lightblue;
width:180px;
float:right; //BFC
}
</pre>
</div>
<div class="center">
中间
<pre>
.center{
background:lightyellow;
overflow:hidden; //BFC
height:116px;
}
</pre>
</div>
</div>
根据BFC的区域不会与float元素重叠
这种规则的特点实现左右两栏宽度固定,中间栏可以根据浏览器宽度自适应。