平时用到的一些布局方法,例如给父元素加overflow:hidden清除子元素浮动,例如给同级的两个块级元素一个加上浮动,另一个加上overflow:hidden来实现一侧定宽,一侧自适应。这些都是对BFC的应用。
BFC规定了内部的块级元素的布局方式,默认情况下只有根元素(即body)一个块级上下文。
BFC布局规则
- 浮动元素会计入BFC的高度。
- 属于同一个BFC的两个相邻的块级元素会发生margin合并,不属于同一个BFC的两个相邻的块级元素不会发生margin合并,BFC区域内的元素的margin不会传递给父级。
- BFC的区域不会和float的元素重合。
- 一个BFC区域的内外元素不会互相影响。
- 在BFC中,每个盒子的左外边框紧挨着包含块的左边框(从右到左的格式化时,则为右边框紧挨)。即使在浮动里也是这样的(尽管一个包含块的边框会因为浮动而萎缩),除非这个包含块的内部创建了一个新的BFC。
如何创建BFC
以下摘自MDN文档
- 根元素或包含根元素的元素
- 浮动元素(元素的 float 不是 none)
- 绝对定位元素(元素的 position 为 absolute 或 fixed)
- 行内块元素(元素的 display 为 inline-block)
- 表格单元格(元素的 display为 table-cell,HTML表格单元格默认为该值)
- 表格标题(元素的 display 为 table-caption,HTML表格标题默认为该值)
- 匿名表格单元格元素(元素的 display为 table、table-row、 table-row-group、table-header-group、table-footer-group(分别是HTML table、row、tbody、thead、tfoot的默认属性)或 inline-table)
- overflow 值不为 visible 的块元素
- display 值为 flow-root 的元素
- contain 值为 layout、content或 strict 的元素
- 弹性元素(display为 flex 或 inline-flex元素的直接子元素)
- 网格元素(display为 grid 或 inline-grid 元素的直接子元素)
- 多列容器(元素的 column-count 或 column-width 不为 auto,包括 column-count 为 1)
- column-span 为 all 的元素始终会创建一个新的BFC,即使该元素没有包裹在一个多列容器中(标准变更,Chrome bug)
BFC的应用场景
1. 清除浮动,防止高度塌陷等问题。
使用overflow:hiden;前,因为parent没设置高度,唯一的子元素又浮动了,导致高度塌陷。
使用overflow:hiden;后,parent作为一个新的BFC,高度计算时算上了浮动的子元素的高度。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div class="parent">
<div class="child"></div>
</div>
</body>
<style>
.parent {
background-color: #4CAF50;
overflow: hidden;
}
.child {
width: 200px;
height: 200px;
background-color: red;
float: left;
}
</style>
</html>
2. margin合并的问题
div one的下外边距为100px,div two的上外边距为50px。实际显示时,两个div之间的间距为100px,不会叠加为150px。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div class="one"></div>
<div class="two"></div>
<style>
.one {
width: 100px;
height: 100px;
background-color: red;
margin-bottom: 100px;
}
.two {
width: 100px;
height: 100px;
background-color: blue;
margin-top: 50px;
}
</style>
</body>
</html>
在div one外层加个父级,写上overflow:hidden,因为生产了一个新的BFC,不属于同一个BFC的两个相邻的块级元素不会发生margin合并,BFC区域内的元素的margin不会传递给父级。div one和div two的间距就变成了150px。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div class="parent">
<div class="one"></div>
</div>
<div class="two"></div>
<style>
.parent {
overflow: hidden;
}
.one {
width: 100px;
height: 100px;
background-color: red;
margin-bottom: 100px;
}
.two {
width: 100px;
height: 100px;
background-color: blue;
margin-top: 50px;
}
</style>
</body>
</html>
3.单侧定宽,另一侧宽度自适应
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div class="all">
<div class="leftBlock">left</div>
<div class="rightBlock">right</div>
</div>
</body>
<style>
* {
margin: 0;
}
.all {
height: 10vh;
width: 100vw;
}
.leftBlock {
width: 300px;
background-color: #4CAF50;
float: left;
height: 100%;
}
.rightBlock {
background-color: antiquewhite;
height: 100%;
overflow: hidden;
}
</style>
</html>