什么是BFC
MDN是这样说明的: 块格式化上下文(Block Formatting Context,BFC) 是Web页面的可视化CSS渲染的一部分,是块盒子的布局过程发生的区域,也是浮动元素与其他元素交互的区域。
uh...,好像不太懂。没关系,通过几个小例子来看看这个“神奇”的东东。
BFC解决浮动溢出问题
通过一个简单的浮动示例来看。比如,有一个div,包含一个左浮动的image和一些文字。如果文字特别多的话,就会环绕浮动的图片。
<div class="outer">
<div class="float">I am a floated element.</div>
I am text inside the outer box.I am text inside the outer box.
I am text inside the outer box.I am text inside the outer box.
I am text inside the outer box.I am text inside the outer box.
</div>
.outer {
border: 5px dotted rgb(214,129,137);
border-radius: 5px;
width: 450px;
padding: 10px;
margin-bottom: 40px;
}
.float {
padding: 10px;
border: 5px solid rgba(214,129,137,.4);
border-radius: 5px;
background-color: rgba(233,78,119,.4);
color: #fff;
float: left;
width: 200px;
margin: 0 20px 0 0;
}
结果:
如果删除一些文字,使它无法环绕图片时,div的边框就会在浮动元素的下面。因为浮动的元素是脱离文档流的,div的宽度不变,高度即为文字的高度,当文字较少时,文字高度低于图片的高度,就会导致div的边框在image的下面。
通常有两种方法来解决这个布局问题,一个是使用clearfix hack,在图片和文本下面插入一个元素,并将其设置为clear:both。另一种方法是使用overflow属性,其值不是默认的visible。
.outer {
...
overflow: auto;
}
overflow之所以有用,是因为使用visible以外任何值都会创建一个块格式化上下文(BFC),BFC的特性之一就是它包含浮动元素。
BFC可以解决外边距重叠问题
比如有一个background为grey的div,div中有两个p元素。div的margin-bottom是40px,p元素的margin-top, margin-bottom各为20px。
<div class="outer">
<p>I am paragraph one and I have a margin top and bottom of 20px</p>
<p>I am paragraph two and I have a margin top and bottom of 20px</p>
</div>
.outer {
background-color: #ccc;
margin: 0 0 40px 0;
}
p {
padding: 0;
margin: 20px 0 20px 0;
background-color: rgb(233,78,119);
color: #fff;
}
由于p元素的边距与外部div的边距之间没有任何内容,这两个边距将会重叠,因此段落将与框的顶部和底部齐平,所以看不到第一个p元素上面的灰色部分,和第二个p元素下面的灰色部分。MDN-外边距重叠
如果我们把div设置成BFC,那么就可以看到边距后的容器的灰色背景了。
.outer {
...
overflow: auto;
}
BFC可以解决内容包裹浮动元素问题
比如一个div包含一个左浮动的元素,和一段文本内容。
<div class="outer">
<div class="float">I am a floated element.</div>
<div class="text">
I am textI am textI am textI am textI am text
I am textI am textI am textI am textI am textI am textI am text
I am textI am textI am textI am text
</div>
</div>
.outer {
border: 5px dotted rgb(214,129,137);
border-radius: 5px;
width: 450px;
padding: 10px;
margin-bottom: 40px;
overflow: auto;
}
.float {
padding: 10px;
border: 5px solid rgba(214,129,137,.4);
border-radius: 5px;
background-color: rgba(233,78,119,.4);
color: #fff;
float: left;
width: 200px;
margin: 0 20px 0 0;
}
当文本内容过长时,便会包裹浮动元素。
可以通过将包装文本的div设置为BFC来防止这种包裹行为。
.text {
overflow: auto;
}
这个其实也是创建有多列的浮动布局的方式。浮动元素本身也会创建一个BFC,所以即使右边的内容比左边的高,也不会包裹左边的元素。
BFC是布局中的一个迷你布局
你可以把BFC想象成页面内部的一个小布局。一旦一个元素创建了一个BFC,元素里面的内容都包含在其中。
块格式化上下文对浮动定位与清除浮动都很重要。浮动定位和清除浮动时只会应用于同一个BFC内的元素。浮动不会影响其它BFC中元素的布局,而清除浮动只能清除同一BFC中在它前面的元素的浮动。外边距折叠也只会发生在属于同一BFC的块级元素之间。
创建BFC的方式
- 根元素()
- 浮动元素(元素的 float 不是 none)
- 绝对定位元素(元素的 position 为 absolute 或 fixed)
- 行内块元素(元素的 display 为 inline-block)
- position: absolute/fixed;
- display: inline-block , table-cell , table-caption。table-cell和table-caption是HTML元素的默认设置,因此table的每个单元格将创建一个BFC。
- overflow 值不为 visible 的块元素
- display 值为 flow-root 的元素。它可以创建无副作用的BFC。在父级块中使用 display: flow-root 可以创建新的BFC。
- contain 值为 layout、content或 paint 的元素
- 弹性元素(display为 flex 或 inline-flex元素的直接子元素)
- 网格元素(display为 grid 或 inline-grid 元素的直接子元素)
- 多列容器(元素的 column-count 或 column-width 不为 auto,包括 column-count 为 1)
- column-span 为 all的元素始终会创建一个新的BFC,即使该元素没有包裹在一个多列容器中)。
最后如果还是糊里糊涂,那就再翻翻MDN的讲解,配合一些小例子效果更佳哟。