BFC

Yuyang 前端小白🥬

BFC

BFC(Block Formatting Context) 是一个独立的渲染区域,只有 Block-level box 参与,它规定了内部的 Block-level box 如何布局,并且与这个区域外部毫不相干。

BFC 的布局规则

  • 内部的 Box 会在垂直方向,一个接一个地放置。
  • Box 垂直方向的距离由 margin 决定,属于同一个 BFC 的两个相邻 Box 的 margin 会发生重叠。
  • 每个元素的 margin box 的左边, 与包含块 border box 的左边相接触(对于从左往右的格式化,否则相反),即使存在浮动也是如此。
  • BFC 的区域不会与 float box 重叠。
  • BFC 就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素,反之也如此。
  • 计算 BFC 的高度时,浮动元素也参与计算。

BFC的触发条件

  • 根元素,即 HTML 元素
  • float 的值不为 none
  • overflow 的值不为 visible
  • display 的值为 inline-block、table-cell、table-caption
  • position 的值为 absolute 或 fixed
  • flex 元素的子元素,且父元素的 display 值为 flex 或 inline-flex

BFC 的应用

  • 阻止 margin 重叠
    属于同一个 BFC 的两个相邻 Box 的 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
    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>BFC 示例</title>
    </head>
    <body>
    <div class="box1"></div>
    <div class="box2"></div>
    </body>
    <style>
    .box1 {
    width: 100px;
    height: 100px;
    background-color: red;
    margin-bottom: 20px;
    }
    .box2 {
    width: 100px;
    height: 100px;
    background-color: blue;
    margin-top: 30px;
    }
    </style>
    </html>

避免重叠可以在box外面包裹一层容器,并触发这个容器生成一个BFC,此时不会出现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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>BFC 示例</title>
</head>
<body>
<div class="box1"></div>
<div class="wrap">
<div class="box2"></div>
</div>
</body>
<style>
.box1 {
width: 100px;
height: 100px;
background-color: red;
margin-bottom: 20px;
}
.wrap {
overflow: hidden;
}
.box2 {
width: 100px;
height: 100px;
background-color: blue;
margin-top: 30px;
}
</style>
</html>

这时候box1和box2的margin不会重叠

  • 清除浮动
    有浮动样式

image-20241020153054705

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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>BFC 示例</title>
</head>
<body>
<div class="container">
<div class="float-box">浮动框 1</div>
<div class="float-box">浮动框 2</div>
</div>

<div class="clearfix-example">
<p>这是另一个段落,如果不清除浮动,它会和上面的浮动框重叠。</p>
</div>
</body>
<style>
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 20px;
background-color: #ffffff;
}

.container {
background-color: #eaf2f8;
padding: 10px;
}

.float-box {
float: left;
width: 100px;
height: 100px;
margin-right: 10px;
background-color: #3498db;
color: white;
text-align: center;
line-height: 100px;
}

.clearfix-example {
background-color: #f9e79f;
padding: 20px;
margin-top: 10px;
overflow: hidden;
}
</style>
</html>

清除浮动后

image-20241020153407574

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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>BFC 示例</title>
</head>
<body>
<div class="container">
<div class="float-box">浮动框 1</div>
<div class="float-box">浮动框 2</div>
</div>

<div class="clearfix-example">
<p>这是另一个段落,如果不清除浮动,它会和上面的浮动框重叠。</p>
</div>
</body>
<style>
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 20px;
background-color: #ffffff;
}

.container {
background-color: #eaf2f8;
padding: 10px;
}

.float-box {
float: left;
width: 100px;
height: 100px;
margin-right: 10px;
background-color: #3498db;
color: white;
text-align: center;
line-height: 100px;
}

.clearfix-example {
background-color: #f9e79f;
padding: 20px;
margin-top: 10px;
overflow: hidden;
}
</style>
</html>
  • 自适应两栏布局
    这里以两栏布局为例

image-20241020154148226

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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>BFC 示例</title>
</head>
<body>
<div class="aside"></div>
<div class="main"></div>
</body>
<style>
body {
width: 300px;
}

.aside {
width: 100px;
height: 100px;
background-color: red;
float: left;
}

.main {
width: 200px;
height: 200px;
background-color: blue;
}

</style>
</html>

每个元素的左外边距与包含块的左边界相接触(从左到右),即使浮动元素也是如此。而BFC的区域不会与浮动盒子重叠,所以可以通过触发main生成一个BFC来实现两栏布局

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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>BFC 示例</title>
</head>
<body>
<div class="aside"></div>
<div class="main"></div>
</body>
<style>
body {
width: 300px;
}

.aside {
width: 100px;
height: 100px;
background-color: red;
float: left;
}

.main {
width: 200px;
height: 200px;
background-color: blue;
overflow: hidden;
}

</style>
</html>

image-20241020203632868