块级格式化上下文(block formating context),是web页面的可视css渲染的一部分,是块盒子布局发生过程中的区域,也是浮动元素与其他元素发生交互的区域。
用更好理解一点的话来说,通过某些特定的方式可以创建一个块级格式化上下文盒子,在这个盒子内部形成了一个区域,区域内的元素不会干扰外界的其他区域,也不受外界的样式影响。
那么,怎样创建一个BFC区域呢?通过以下方式可以创建块级格式化上下文:
常见的BFC
- 根元素,即html
- 浮动元素,即元素的float树形不为none
- 浮动定位元素,即元素的position是absolute、fixed
- 行内块元素,即display为inline-block的元素
- overflow属性不是visible的元素
- 弹性盒子
- 表格单元格,即tr、td以及display为table-cell的元素
- 表格标题
还有些其他的不常用,就不列举出来了。
BFC的特性
边距重叠的现象
同一个BFC元素内的块级元素会发生边距重叠现象,看一段html示例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<style>
div {
width: 100px;
height: 100px;
margin: 100px;
background: #1890ff;
}
</style>
<body>
<div></div>
<div></div>
</body>
</html>
上面2个div出在根元素body下边,body默认是bfc元素,因此,bfc中的两个块级元素div发生了外边距margin重叠的情况:
BFC区域不会与浮动元素重叠
如果一个元素是BFC,那么,它不会跟它旁边的浮动元素发生重叠,而是按顺序依次排列,看下示例:
首先演示一下,非bfc元素与浮动元素的布局情况
<style>
.flow-div {
float: left;
width: 100px;
height: 100px;
background: aqua;
}
.not-bfc-div {
width: 200px;
height: 200px;
background: bisque;
}
</style>
<body>
<div class="flow-div"></div>
<div class="not-bfc-div"></div>
</body>
可以看到,not-fbc-div这个盒子由于不是bfc,所以,它跟浮动元素flow-div发生了重叠
怎样取消这种情况?通过修改not-bfc-div的属性,增加overflow:hidden或者display:inline-block,使其变成BFC即可。
<style>
.flow-div {
float: left;
width: 100px;
height: 100px;
background: aqua;
}
.bfc-div {
overflow: hidden;
width: 200px;
height: 200px;
background: bisque;
}
</style>
<body>
<div class="flow-div"></div>
<div class="bfc-div"></div>
</body>
这时可以看到,BFC与浮动元素不再重叠:
BFC解决了哪些问题?
浮动元素周边的文字环绕
<style>
.flow-div {
float: left;
width: 100px;
height: 100px;
background: aqua;
}
.not-bfc-div {
/* overflow: hidden; */
width: 200px;
height: 200px;
background: bisque;
white-space: pre-wrap;
}
</style>
<body>
<div>
<div class="flow-div">12</div>
<div class="not-bfc-div">子元素浮动,父元素高度塌陷 外边距塌陷 浮动元素周围文字环绕问题子元素浮动,父元素高度塌陷 外边距塌陷 浮动元素周围文字环绕问子元素浮动问</div>
</div>
</body>
可以看到,非BFC元素文字围绕着浮动元素布局展示:
将not-bfc-div改成BFC
<style>
.flow-div {
float: left;
width: 100px;
height: 100px;
background: aqua;
}
.bfc-div {
overflow: hidden;
width: 200px;
height: 200px;
background: bisque;
white-space: pre-wrap;
}
</style>
<body>
<div>
<div class="flow-div">12</div>
<div class="not-bfc-div">子元素浮动,父元素高度塌陷 外边距塌陷 浮动元素周围文字环绕问题子元素浮动,父元素高度塌陷 外边距塌陷 浮动元素周围文字环绕问子元素浮动问</div>
</div>
</body>
此时,文字将不再环绕着浮动元素布局:
解决浮动元素导致父元素高度塌陷的问题
当一个父元素内部的子元素有浮动属性时,该父元素的高度将不会被子元素撑开:
<style>
.outer {
background: blueviolet;
border: 1px solid;
}
.not-bfc-div {
float: left;
width: 200px;
height: 200px;
background: bisque;
white-space: pre-wrap;
}
</style>
<body>
<div class="outer">
<div class="not-bfc-div"></div>
</div>
</body>
可以看到,该父元素的高度仅仅由于1px的边框而产生了2px的高度:
将父元素改为BFC之后。(注意,这里是将父元素改为BFC,这样,当父元素计算高度时,子元素即时是浮动元素,也会参与父元素的高度计算):
可以看到,紫色的父元素的高度已经被子元素撑开,高度变成了子元素的高度加上自身的border宽度。
两栏自适应布局
后面将不再展示代码,只直接将方法。
方法:两个div在同一水平上需要横向展示,并且一个固定宽度并设置float:left,一个自适应时,给固定的元素设定固定的宽度,给自使用的元素开启BFC即可。
原理:BFC的区域不会与float元素发生重叠。