BFC,Block Formatting Context,块级格式化上下文,是一个独立的渲染区域或隔离的独立容器,它决定了其子元素如何布局,并且与这个区域外部的元素无关。
形成 BFC 的条件
- float 的值不为 none(left、right)
- overflow 的值不为 visible(hidden、auto、scroll)
- display 的值为 table-cell、table-caption、inline-block、flex、inline-flex
- position 的值为 absolute 或 fixed
- <html> 根元素
BFC 的特性
- 内部的 Box 会在垂直方向,一个接一个的放置。即使存在浮动也是如此。
- Box 垂直方向的距离由 margin 决定。属于同一个 BFC 的两个相邻的 Box 的 margin 会发生重叠。
- BFC 的区域不会与 float box 重叠(定位情况除外)。
- BFC 是一个页面上的独立容器,容器里面的子元素不会影响到外面的元素,反之亦然。
- 计算 BFC 的高度时,浮动元素也参与计算。
BFC 可以解决的问题
- 解决浮动导致的父元素高度塌陷问题
问题:当父元素没有设置固定高度且子元素都浮动时,父元素会出现高度塌陷。
<html>
<style>
.container {
width: 300px;
border: 1px solid red;
/* overflow: hidden; */
}
.item {
background-color:orange;
float: left;
width: 100px;
height: 100px;
}
</style>
<body>
<div class="container">
<div class="item"></div>
</div>
</body>
</html>
解决方案:父元素样式增加 overflow: hidden;
最终效果:
- 解决外边距合并问题
问题:普通文档流中,处于同一个 BFC 中的块级元素之间的垂直外边距会发生外边距合并。合并后的外边距的高度等于两个发生合并的外边距的高度中的较大者。
<html>
<style>
.item1, .item2 {
background-color:orange;
width: 100px;
height: 100px;
}
.item1 {
margin-bottom: 70px;
}
.item2 {
margin-top: 30px;
}
</style>
<body>
<div class="container">
<div class="item1"></div>
<div class="item2"></div>
</div>
</body>
</html>
此时,两个盒子之间的垂直间距等于最大的外边距 70,而不是两个外边距之和 100。
解决方案:任意选择一个子元素创建 BFC(如 box)
<html>
<style>
.item1, .item2 {
background-color:orange;
width: 100px;
height: 100px;
}
.item1 {
margin-bottom: 70px;
}
.item2 {
margin-top: 30px;
}
.box {
overflow: hidden;
}
</style>
<body>
<div class="container">
<div class="item1"></div>
<div class="box">
<div class="item2"></div>
</div>
</div>
</body>
</html>
最终效果:
3. 解决文字环绕问题 / 实现两栏布局
问题:正常情况下,左侧元素浮动时,会与右侧元素重叠,形成文字环绕效果,从而无法实现两栏布局。
<html>
<style>
.container {
width: 300px;
}
.item1 {
background-color:orange;
width: 100px;
height: 100px;
float: left;
}
.item2 {
background-color: #d0e4fe;
}
</style>
<body>
<div class="container">
<div class="item1">左侧浮动元素</div>
<div class="item2">右侧非浮动元素会环绕在浮动元素的右侧,达到文字环绕的效果。父元素的高度取决于右侧内容的高度。如果右侧内容较少,会造成父元素高度塌陷;如果右侧内容足够多,则会继续填充到浮动元素的下方。</div>
</div>
</body>
</html>
解决方案:给右侧元素设置 overflow: hidden; 来形成 BFC。
最终效果: