浅谈对BFC的理解
对于前端开发人员来说肯定是知道盒模型(margin,border, padding, content)这个概念,对一个元素设置CSS,首先需要知道这个元素是block还是inline类型。而BFC就是用来格式化块级盒子,同样管理inline类型的盒子还有IFC,以及其他的FC。
1. FC的概念。
Formatting Context:指页面中的一个渲染区域,并且拥有一套渲染规则,他决定了其子元素如何定位,以及与其他元素的相互关系和作用。
2. 什么是BFC
2.1 概念
块级格式化上下文,它是指一个独立的块级渲染区域,只有Block-level BOX参与,该区域拥有一套渲染规则来约束块级盒子的布局,且与区域外部无关。
注意: BFC 是W3C CSS 2.1 规范中的一个概念,在CSS3中被修改为float root。
2.2 BFC的生成
- 浮动元素(float: left | right)
- 绝对定位元素(position: absolute | fixed)
- overflow的值不为visible
- 行内块元素(display:inline-block)
- 表格单元格(display:table-cells,td, th)
- 表格的标题(display:table-captions)
- 注意:
- disable:table之所以也可以是因为table默认会生成一个匿名的table-cell。正是因为匿名的table-cell生成了BFC
- 是这些元素创建了BFC,他们本身不是BFC
2.3 BFC的约束规则
浏览器对于BFC这块区域的约束规则如下:
- 生成BFC元素的子元素会一个接一个的放置。垂直方向上他们的起点是一个包含块的顶部,两个相邻子元素之间的垂直距离取决于元素的margin特性。在BFC中相邻的块级元素外边距会折叠(即margin重叠)。
- 生成BFC元素的子元素中,每一个子元素做外边距与包含块的左边界相接触,(对于从右到左的格式化,右外边距接触右边界),即使浮动元素也是如此(尽管子元素的内容区域会由于浮动而压缩),除非这个子元素也创建了一个新的BFC(如它自身也是一个浮动元素)
网友解析
内部的Box会在垂直方向上一个接一个的放置
垂直方向上的距离由margin决定。(完整的说法是:属于同一个BFC的两个相邻Box的margin会发生重叠,与方向无关。)
每个元素的左外边距与包含块的左边界相接触(从左向右),即使浮动元素也是如此。(这说明BFC中子元素不会超出他的包含块,而position为absolute的元素可以超出他的包含块边界)
BFC的区域不会与float的元素区域重叠
计算BFC的高度时,浮动子元素也参与计算
BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面元素,反之亦然
css相关规则
- Block元素会扩展到与父元素同宽,所以block元素会垂直排列
- 垂直方向上的两个相邻DIV的margin会重叠,而水平方向不会(此规则并不完全正确)
- 浮动元素会尽量接近往左上方(或右上方)
- 为父元素设置overflow:hidden或浮动父元素,则会包含浮动元素
2.4 BFC的应用
防止margin重叠
案例上下margin重叠
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56<!--
* @Autor: Clairoll
* @Date: 2020-12-14 11:18:24
* @LastEditTime: 2020-12-14 11:39:56
* @Email: [email protected]
* @description:
-->
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<style>
html,
body {
height: 100%;
width: 100%;
margin: 0;
padding: 0;
}
#map {
padding: 0;
}
.first {
margin: 20px;
background: lightgreen;
width: 100px;
height: 100px;
}
ul {
/* display:inline-block; */
margin: 10px;
background: lightblue;
}
li {
margin: 25px;
}
</style>
<body class="claro">
<div class="first"></div>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
</body>
</html>解决
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59<!--
* @Autor: Clairoll
* @Date: 2020-12-14 11:18:24
* @LastEditTime: 2020-12-14 11:44:53
* @Email: [email protected]
* @description:
-->
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<style>
html,
body {
height: 100%;
width: 100%;
margin: 0;
padding: 0;
}
#map {
padding: 0;
}
.first {
margin: 20px;
background: lightgreen;
width: 100px;
height: 100px;
}
ul {
display:inline-block; // 通过此处生成BFC
/* overflow:hidden; */
/*float: left;*/
/*position: absolute;*/
margin: 10px;
background: lightblue;
}
li {
margin: 25px;
}
</style>
<body class="claro">
<div class="first"></div>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
</body>
</html>
浮动相关布局问题
多栏布局