什么是BFC ?
BFC(Block Fromatting Context),即块级格式化上下文,是一个独立的布局环境,其中的元素布局是不受外界的影响,并且在一个BFC中,块盒与行盒(行盒由一行中所有的内联元素所组成)都会垂直的沿着其父元素的边框排列。
什么样的环境才是BFC ?
只需要满足一个或者多个条件即可:
- float的值不是none。
- position的值不是static或者relative。
- display的值是inline-block、table-cell、flex、table-caption或者inline-flex
- overflow的值不是visible
BFC的副作用:
- display: table 可能引发响应性问题
- overflow: scroll 可能产生多余的滚动条
- float: left 将把元素移至左侧,并被其他元素环绕
- overflow: hidden 将裁切溢出元素
BFC作用:
- 避免外边距重叠:BFC可能造成外边距折叠,也可以利用它来避免这种情况。BFC产生外边距折叠要满足一个条件:两个相邻元素要处于同一个BFC中。所以,若两个相邻元素在不同的BFC中,就能避免外边距折叠。
例:外边距重叠情况:
<div class="container">
<p>Sibling 1</p>
<p>Sibling 2</p>
<p>Sibling 3</p>
</div>
.container {
background-color: red;
overflow: hidden; /* 创建一个BFC环境 */
}
p {
background-color: lightgreen;
margin: 10px 0;
}
则像上面的代码,会出现下图的外边距重叠
经过BFC的设置可以避免外边距重叠,设置的相应代码为:
<div class="container">
<p>Sibling 1</p>
<p>Sibling 2</p>
<div class="newBFC">
<p>Sibling 3</p>
</div>
</div>
.container {
background-color: red;
overflow: hidden; /* 创建一个BFC */
}
p {
margin: 10px 0;
background-color: lightgreen;
}
.newBFC {
overflow: hidden; /* 在创建一个BFC,使得最后两个P元素在不同的BFC中 */
}
则效果如下:
- BFC包含浮动: 浮动元素是会脱离文档流的(绝对定位元素会脱离文档流)。如果一个没有高度或者height是auto的容器的子元素是浮动元素,则该容器的高度是不会被撑开的。我们通常会利用伪元素(:after或者:before)来解决这个问题。BFC能包含浮动,也能解决容器高度不会被撑开的问题。
案例如下:
没有加BFC的情况
div class="container">
<div>Sibling</div>
<div>Sibling</div>
</div>
CSS:
.container {
background-color: green;
}
.container div {
float: left;
background-color: lightgreen;
margin: 10px;
}
效果如下:
在通过BFC设置之后:
.container {
overflow: hidden; /* 创建一个BFC,使得父元素被撑开 */
background-color: green;
}
.container div {
float: left;
background-color: lightgreen;
margin: 10px;
}
效果如下:
- 使用BFC避免文字环绕
如上图所示,对于浮动元素,可能会造成文字环绕的情况(Figure1),但这并不是我们想要的布局(Figure2才是想要的)。要解决这个问题,我们可以用外边距,但也可以用BFC
如例:
<div class="container">
<div class="floated">
Floated div
</div>
<p>
Quae hic ut ab perferendis sit quod architecto,
dolor debitis quam rem provident aspernatur tempora
expedita.
</p>
</div>
该代码的效果为:
上图整个黑色区域表示 p 元素。p 元素没有移位但它叠在了浮动元素之下,而p元素的文本(行盒子)却移位了,行盒子水平变窄来给浮动元素腾出了空间。随着文本的增加,最后文本将环绕在浮动元素之下,因为那时候行盒子不再需要移位,也就成了图Figure1的样子
-
在多列布局中使用BFC:如果我们创建一个占满整个容器宽度的多列布局,在某些浏览器中最后一列有时候会掉到下一行。这可能是因为浏览器四舍五入了列宽从而所有列的总宽度会超出容器。但如果我们在多列布局中的最后一列里创建一个新的BFC,它将总是占据其他列先占位完毕后剩下的空间。
案例代码如下:
<div class="container">
<div class="column">column 1</div>
<div class="column">column 2</div>
<div class="column">column 3</div>
</div>
.column {
width: 31.33%;
background-color: green;
float: left;
margin: 0 1%;
}
/* Establishing a new block formatting
context in the last column */
.column:last-child {
float: none;
overflow: hidden;
}
现在尽管盒子的宽度稍有改变,但布局不会打破。当然,对多列布局来说这不一定是个好办法,但能避免最后一列下掉。这个问题上弹性盒或许是个更好的解决方案,但这个办法可以用来说明元素在这些环境下的行为。