BFC

本文最后更新于:1 年前

BFC

参考资料:MDN: Block formatting context

什么是 BFC

BFC(Block Formatting Context,块格式化上下文)是 Web 页面中可视的 CSS 渲染的一部分,它是块盒子布局时所在的区域,该区域中的浮动元素与其他元素相互作用(即清除浮动的作用)。

我的理解:就是页面中的一个渲染区域,该区域是块级的,并且该区域中的浮动元素不影响其它 BFC 中元素的布局(所以该特性经常被用来清除浮动)。

BFC就是一个独立不干扰外界也不受外界干扰的盒子

BFC 规则

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

创建BFC :

  • 根元素<html>
  • float的值不为none
  • overflow的值不为visible
  • display的值为inline-block、table-cell、table-caption
  • position的值为absolute或fixed

BFC的应用

1、自适应两栏布局
2、清除内部浮动
3、防止margin上下重叠(解决margin叠加问题)

自适应两栏布局

左边固定,右边自适应
为.main元素的样式加上overflow:hidden;使其建立一个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
  <style>
.container {
width: 100%;
position: relative;
}
.aside {
width: 100px;
height: 150px;
float: left;
background-color: #f66;
}
.main {
height: 200px;
background-color: #fcc;
overflow: hidden;
}
</style>
</head>
<body>
<div class="container">
<div class="aside"></div>
<div class="main"></div>
</div>
</body>

image.png

清除浮动,计算BFC的高度

我们都知道浮动会脱离文档流,接下来我们看看下面的例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<style>
.box1{
width:100px;
height:100px;
float:left;
border: 1px solid #000;
}
.box2{
width:100px;
height:100px;
float:left;
border: 1px solid #000;
}
.box{
background:yellow
}
</style>
<body>
<div class="box">
<div class="box1"></div>
<div class="box2"></div>
</div>
</body>

image.png
由于容器内两个div元素浮动,脱离了文档流,父容器内容宽度为零(即发生高度塌陷),未能将子元素包裹住。解决这个问题,只需要把把父元素变成一个BFC就行了。常用的办法是给父元素设置overflow:hidden
父级添加overflow属性,通过触发BFC的方式,清除浮动效果。
image.png

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<style>
.box1{
width:100px;
height:100px;
float:left;
border: 1px solid #000;
}
.box2{
width:100px;
height:100px;
float:left;
border: 1px solid #000;
}
.box{
background:yellow;
overflow: hidden;
}
</style>
<body>
<div class="box">
<div class="box1"></div>
<div class="box2"></div>
</div>
</body>

解决margin叠加问题

按照BFC的定义,只有同属于一个BFC时,两个元素才有可能发生垂直margin的重叠,这个包括相邻元素或者嵌套元素,只要他们之间没有阻挡(比如边框、非空内容、padding等)就会发生margin重叠。

①相邻兄弟元素margin重叠问题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<style>
p {
color: #fff;
background: #888;
width: 200px;
line-height: 100px;
text-align: center;
margin: 100px;
}
</style>
<body>
<p>ABC</p>
<p>abc</p>
</body>

image.png
上面例中两个P元素之间距离本该为200px,然而实际上只有100px,发生了margin重叠。遇到这种情形,我们如何处理?
只需要在p外面包裹一层容器,并触发该容器生成一个BFC。那么两个P便不属于同一个BFC,就不会发生margin重叠了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<style>
p {
color: #fff;
background: #888;
width: 200px;
line-height: 100px;
text-align: center;
margin: 100px;
}
.wrap {
overflow: hidden;
}
</style>
<body>
<p>ABC</p>
<div class="wrap">
<p>abc</p>
</div>
</body>

image.png

②父子元素margin重叠问题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<style>
.box {
width: 100px;
height: 100px;
background: #ccc;
}
.wrap {
background: yellow;
}
.wrap h1 {
background: pink;
margin: 40px;
}
</style>
<body>
<div class="box">box</div>
<div class="wrap">
<h1>h1</h1>
</div>
</body>

image.png
wrap元素与h1元素之间理论上本该有个40px的上下margin值,然而实际上父子元素并没有存在margin值,与此同时,两个div元素的间距为40px。遇到这种情形,我们如何处理?
处理方法其实有很多,在wrap元素中添加:overflow:hidden;或者overflow:auto;使其父元素形成一个BFC;也可以在wrap元素中添加border:1px solid;或是padding:1px,这些都可以有效解决父子元素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
<style>
.box {
width: 100px;
height: 100px;
background: #ccc;
}
.wrap {
background: yellow;
/* overflow: hidden; */
/* overflow: auto; */
/* padding: 1px; */
border: 1px solid;
}
.wrap h1 {
background: pink;
margin: 40px;
}
</style>
<body>
<div class="box">box</div>
<div class="wrap">
<h1>h1</h1>
</div>
</body>

image.png


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!