对一个元素设置css,首先需要知道这个元素是block还是inline类型。而BFC就是用来格式化块级盒子。
- Formatting Context:指页面中一个渲染区域,并且拥有一套渲染规则,他决定了其子元素如何定位,以及与其他元素的相互关系和作用。
- BFC:块级格式化上下文,它是指一个独立的块级渲染区域,只有Block-level Box参与,该区域拥有一套渲染规则来约束块级盒子的布局,且与区域外部无关。
BFC的生成
1. float的值不为none;
2. overflow的值不为visible;(overflow的值有visible,hidden,scroll,auto,inherit)
3. display的值为inline-block、table-cell、table-caption;
4. position的值为absolute或fixed;
5. 看到有人把display:table也认为可以生成BFC,其实这里的主要原因在于Table会默认生成一个匿名的table-cell,正是这个匿名的table-cell生成了BFC。
BFC布局规则
1. 内部的Box会在垂直方向,一个接一个地放置。
2. Box垂直方向的距离由margin决定。属于同一个BFC的两个相邻Box的margin会发生重叠
3. 每个元素的margin box的左边, 与包含块border box的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此。
4. BFC的区域不会与float box重叠。
5. BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。
6. 计算BFC的高度时,浮动元素也参与计算
哪些元素会生成BFC
1. 根元素
2. float属性不为none
3. position为absolute或fixed
4. display为inline-block, table-cell, table-caption, flex, inline-flex
5. overflow不为visible
BFC在布局中的应用
多栏布局的一种方式
<style type="text/css">
body{padding: 0;margin: 200px;}
body{
width: 300px;
position: relative;
}
.aside{
width: 100px;
height: 150px;
float: left;
background-color: #f66;
}
.main{
height: 200px;
background: #fcc;
}
</style>
<body>
<div class="aside"></div>
<div class="main"></div>
</body>
根据BFC布局规则第3条:
每个元素的margin box的左边, 与包含块border box的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此。
因此,虽然存在浮动的元素aside,但main的左边依然会与包含块的左边相接触。
根据BFC布局规则第四条:
BFC的区域不会与float box重叠。
我们可以通过触发main生成BFC, 来实现自适应两栏布局。
.main{
height: 200px;
background: #fcc;
overflow: hidden;
}
浮动相关问题
<style type="text/css">
.par{
border: 5px solid #fcc;
width: 300px;
margin:200px;
}
.child{
border: 5px solid #f66;
width: 100px;
height: 100px;
float: left;
}
</style>
<body>
<div class="par">
<div class="child"></div>
<div class="child"></div>
</div>
</body>
根据BFC布局规则第六条:
计算BFC的高度时,浮动元素也参与计算
解决方案一般有两种
1). 利用 clear属性,清除浮动
给父元素添加floatfix
.floatfix{
*zoom:1;
}
.floatfix:after{
content: "";
display: table;
clear: both;
}
2). 使父容器形成BFC
.par{
overflow:hidden;
}
防止margin重叠
<body>
<p>Haha</p>
<p>Hehe</p>
</body>
p{
color: #f55;
background: #fcc;
width: 200px;
line-height: 100px;
text-align: center;
margin: 100px;
}
两个p之间的距离为100px,发送了margin重叠。
根据BFC布局规则第二条:
Box垂直方向的距离由margin决定。属于同一个BFC的两个相邻Box的margin会发生重叠。
折叠的结果:
1. 两个相邻的外边距都是正数时,折叠结果是它们两者之间较大的值。
2. 两个相邻的外边距都是负数时,折叠结果是两者绝对值的较大值。
3. 两个外边距一正一负时,折叠结果是两者的相加的和。
我们可以在p外面包裹一层容器,并触发该容器生成一个BFC。那么两个P便不属于同一个BFC,就不会发生margin重叠了。
<body>
<p>Haha</p>
<div class="wrap">
<p>Hehe</p>
</div>
</body>
.wrap{
overflow: hidden;
}
浮动和绝对定位不与任何元素产生 margin 折叠
原因:
浮动元素和绝对定位元素不与其他盒子产生外边距折叠是因为元素会脱离当前的文档流,违反了上面所述的两个margin是邻接的条件同时,又因为浮动和绝对定位会使元素为它的内容创建新的BFC,因此该元素和子元素所处的BFC是不相同的,因此也不会产生margin的折叠。
外边距合并
- 毗邻的两个兄弟元素之间的外边距会塌陷(除非后者兄弟姐妹需要清除过去的浮动)
- 如果块级父元素中,不存在上边框、上内边距、内联元素、 清除浮动 这四条属性(也可以说,当上边框宽度及上内边距距离为0时),那么这个块级元素和其第一个子元素的上边距就可以说”挨到了一起“。此时这个块级父元素和其第一个子元素就会发生上外边距合并现象,换句话说,此时这个父元素对外展现出来的外边距将直接变成这个父元素和其第一个子元素的margin-top的较大者。
类似的,若块级父元素的 margin-bottom 与它的最后一个子元素的margin-bottom 之间没有父元素的 border、padding、inline content、height、min-height、 max-height 分隔时,就会发生 下外边距合并 现象。 - 如果存在一个空的块级元素,其 border、padding、inline content、height、min-height 都不存在。那么此时它的上下边距中间将没有任何阻隔,此时它的上下外边距将会合并.