BFC 为何物
格式化上下文(Block Formatting Context),是 Web 页面中盒模型布局的 CSS 渲染模式,主要指一个独立的渲染区域或一个隔离的独立容器。
需要什么条件(即如何脱离文档流)
- 根元素(HTML元素),最大的一个BFC;
- 浮动元素,
float
除none
以外的值; - 定位元素,
position: [absolute | fixed]
; display: [inline-block | table-cell | table-caption]
;overflow: [hidden | auto | scroll]
, 即除visible
以外的值;
看例子
BFC 中的盒子对齐垂直存放
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>BFC 对齐</title>
<style>
* { margin: 0; padding: 0; }
.absolute { position: absolute; }
.left { float: left; }
.section { width: 520px; }
.section1 { background-color: red; min-height: 40px; }
.section2 { background-color: orange; min-height: 40px; }
.section3 { background-color: yellow; width: 100px; min-height: 40px; }
.section4 { background-color: green; min-height: 60px; }
</style>
</head>
<body>
<div class="section">
<div class="section1">section1</div>
<div class="section2">section2</div>
<div class="section3 left">section3 float</div>
<div class="section4">section4</div>
</div>
</body>
</html>
哪怕浮动元素(section3)也接着上一个盒子垂直排列(所有的盒子都左对齐)。
外边距折叠
例子1 |
例子2 |
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>BFC margin</title>
<style>
* { margin: 0; padding: 0; }
.hidden { overflow: hidden; }
.section { margin: 20px auto; border:1px solid red; width: 800px; }
.section1 { background-color: orange; margin: 10px; min-height: 40px; }
.section2 { background-color: green; margin: 30px; min-height: 60px; }
</style>
</head>
<body>
<div class="section">
<div class="section1"></div>
<div class="section2"></div>
</div>
<div class="section">
<div class="hidden">
<div class="section1"></div>
</div>
<div class="section2"></div>
</div>
</body>
</html>
例子1:两个内部盒子 section1
和 section2
的垂直距离为 30px
而不是 40px
,因为垂直外边距会折叠,间距以较大的为准;
例子2:如何解决垂直外边距不折叠呢?其实只要让 BFC 容器里的元素不会影响外面元素,同样外面元素不影响 BFC 容器里的元素,即让 section1
或 section2
中一个盒子处于一个 BFC 容器中就行了;
不被浮动元素覆盖
例子1 |
例子2 和 例子3 |
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>BFC float</title>
<style>
* { margin: 0; padding: 0; }
.hidden{ overflow: auto;}
.left { float: left; }
.right { float: right; }
.section { margin: 20px auto; border: 1px solid red; width: 800px; }
.section1 { background-color: orange; width: 100px; min-height: 40px; margin-right: 10px; }
.section2 { min-height: 60px; background-color: green;}
.section3 { background-color: pink; width: 100px; min-height: 40px; margin-left: 10px; }
</style>
</head>
<body>
<div class="section">
<div class="section1 left">
<p>section1</p>
<p>section1</p>
</div>
<div class="section2">
<p>section2</p>
<p>section2</p>
<p>section2</p>
<p>section2</p>
</div>
</div>
<div class="section">
<div class="section1 left">
<p>section1</p>
<p>section1</p>
</div>
<div class="section2 hidden">
<p>section2</p>
<p>section2</p>
<p>section2</p>
<p>section2</p>
</div>
</div>
<div class="section">
<div class="section1 left">
<p>section1</p>
<p>section1</p>
</div>
<div class="section3 right">
<p>section3</p>
<p>section3</p>
</div>
<div class="section2 hidden">
<p>section2</p>
<p>section2</p>
<p>section2</p>
<p>section2</p>
</div>
</div>
</body>
</html>
- 例子1:字体环绕,浮动的盒子会遮盖下面的盒子,但是下面盒子里的文字是不会被遮盖的,文字反而还会环绕浮动的盒子(挺有有趣的),如何阻止文字环绕,可看例子2;
- 例子2:两栏布局,左边固定宽度,右边不设宽(宽度自适应,随浏览器窗口大小的变化而变化);
- 例子3:三栏布局,左右两边固定宽度,中间不设宽(宽度自适应,随浏览器的大小变化而变化);
BFC 包含浮动的块
其实就是清浮动(利用 overflow:hidden
),可看面试之道之 CSS 布局
最后
总结下特征(能解决哪些问题)
- 内部的 box 在垂直方向存放;
- 垂直方向上的距离由
margin
决定(外间距之和); - BFC 的区域不会与
float
元素区域重叠(阻止文字环绕和实现多栏布局); - 计算 BFC 的高度时,浮动元素也参与计算(清浮动);
- bfc 是页面上的一个独立容器,容器里的子元素不会影响外面元素;