BFC定义:
浮动元素和绝对定位元素,非块级盒子的块级容器(例如 inline-blocks, table-cells, 和 table-captions),以及overflow值不为“visiable”的块级盒子,都会为他们的内容创建新的BFC(块级格式化上下文)。
BFC是一个独立的布局环境,其中的元素布局是不受外界的影响,并且在一个BFC中,块盒与行盒(行盒由一行中所有的内联元素所组成)都会垂直的沿着其父元素的边框排列。可以把 BFC 理解为一个封闭的大箱子,箱子内部的元素无论如何翻江倒海,都不会影响到外部。
BFC触发条件:
BFC布局规则:
1.内部的Box会在垂直方向,一个接一个地放置(不设置浮动,设置浮动那肯定是 左右一行排列了)。
2.Box垂直方向的距离由margin决定。属于同一个BFC的两个相邻Box的margin会发生重叠(正常的不设置浮动,两个块元素margin重叠,仅仅是垂直方向,左右不是这个样子的)
3.每个元素的margin box的左边, 与包含块border box的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此。(不设置浮动,不设置左边距,块级子元素,一律靠左竖直向下排列,内联子元素一律从左向右排列,想想,正常写代码,都是这样,设置左浮动的靠近父元素的左边,设置右浮动,靠近父元素的右边。)
4.BFC的区域不会与float box重叠。BFC区域的子元素不受外面的影响,外面的也不受BFC区域里面的影响(这个挺重要的,设置的浮动的元素,脱离了文档流,正常的相邻的元素会跑到它下面(靠左)。设置成BFC,自己独成一块,不会跑到它下面,而是保持洁身自好,自己依然占一块。)
5.计算BFC的高度时,浮动元素也参与计算(就是子元素设置浮动,脱离文档流,父元素高度塌陷,给父元素设置BFC,那么父元素高度就不会忽略浮动的子元素,从而高度就不会塌陷,这样理解,好像是BFC又把脱离文档流的元素,又拉回来了,但保持了浮动的特点。)
主要用途: 外边距折叠
<div class="container">
<p>Sibling 1</p>
<p>Sibling 2</p>
</div>
.container {
background-color: red;
overflow: hidden; /* creates a block formatting context */
}
p {
background-color: lightgreen;
margin: 10px 0;
}
在上图中,一个红盒子(div)包含着两个兄弟元素(p),一个BFC已经创建了出来。
理论上,两个p元素之间的外边距应当是二者外边距之和(20px)但实际上却是10px,这是外边距折叠(Collapsing Margins)的结果。
产生折叠的必备条件:margin必须是邻接的。
在CSS当中,相邻的两个盒子(可能是兄弟关系也可能是祖先关系)的外边距可以结合成一个单独的外边距。这种合并外边距的方式被称为折叠,并且因而所结合成的外边距称为折叠外边距。折叠的结果按照如下规则计算:
1、两个相邻的外边距都是正数时,折叠结果是它们两者之间较大的值。
2、两个相邻的外边距都是负数时,折叠结果是两者绝对值的较大值。
3、两个外边距一正一负时,折叠结果是两者的相加的和。
利用BFC避免外边距折叠
<div class="container">
<p>Sibling 1</p>
<div class="container1">
<p>Sibling 2</p>
</div>
</div>
.container {
background-color: red;
overflow: hidden; /* creates a block formatting context */
}
p {
background-color: lightgreen;
margin: 10px 0;
}
.container1{
overflow: hidden;
}
因为第一个和第二个P元素现在分属于不同的BFC,它们之间就不会发生外边距折叠了。
BFC清除浮动
浮动元素是会脱离文档流的(绝对定位元素会脱离文档流)。如果一个没有高度或者height是auto的容器的子元素是浮动元素,则该容器的高度是不会被撑开的。我们通常会利用伪元素(:after或者:before)来解决这个问题。BFC能包含浮动,也能解决容器高度不会被撑开的问题。
<div class="container">
<div>Sibling</div>
<div>Sibling</div>
</div>
.container {
background-color: blue;
overflow: hidden; // 添加后才能实现BFC,才能包住浮动元素
}
.container div {
float: left;
background-color: lightgreen;
margin: 10px;
}
未添加overflow: hidden
添加overflow: hidden
阻止元素被浮动元素覆盖
<div style="height: 100px;width: 100px;float: left;background: lightblue">
我是一个左浮动的元素 one
</div>
<div style="width: 200px; height: 200px;background: grey">
我是一个没有设置浮动,也没有触发 BFC 元素,我想你这次只是生气时间久了一点,是的。
</div>
<div style="height: 100px;width: 100px;float: left;background: lightblue">
我是一个左浮动的元素 two
</div>
<div style="width: 200px; height: 200px;background: grey;overflow:hidden">
我是一个没有设置浮动,也没有触发 BFC 元素,我想你这次只是生气时间久了一点,是的。
</div>
由于左侧块级元素发生了浮动,所以和右侧未发生浮动的块级元素不在同一层内,所以会发生div遮挡问题。可以给右侧元素添加 overflow: hidden,触发BFC来解决遮挡问题。