BFC的概念
CSS规范对其的定义是:浮动,绝对定位元素,非块盒的块容器(例如,inline-blocks,table-cells和table-captions)和'overflow'不为'visible'的块盒会为它们的内容建立一个新的块格式化上下文
- Formatting context(格式化上下文) 是 W3C CSS2.1 规范中的一个概念。它是页面中的一块渲染区域,并且有一套渲染规则,它决定了其子元素将如何定位,以及和其他元素的关系和相互作用。
- BFC 即 Block Formatting Contexts (块级格式化上下文),具有 BFC 特性的元素可以看作是隔离了的独立容器,容器里面的元素不会在布局上影响到外面的元素,并且 BFC 具有普通容器所没有的一些特性。
- 在Normal Flow中盒子要么属于块级格式化上下文,要么属于内联格式化上下文
BFC的产生(BFC只对其子元素生效)
- 根元素<html>
- float属性不为none(不推荐)
使用这种方式开启,虽然可以撑开父元素,但是会导致父元素的宽度丢失,而且使用这种方式也会导致下边的元素上移,不能解决问题 - position为absolute或fixed(不推荐)
- display为inline-block,flex或者inline-flex(不推荐)
可以解决问题,但是会导致宽度丢失,不推荐使用这种方式 - overflow不为visible(当overflow为visible时它的子元素可进入其他的或者说自己外层的BFC中)
参考另一种:
根元素或其它包含它的元素
浮动元素 (元素的 float 不是 none)
绝对定位元素 (元素具有 position 为 absolute 或 fixed)
内联块 (元素具有 display: inline-block)
表格单元格 (元素具有 display: table-cell,HTML表格单元格默认属性)
表格标题 (元素具有 display: table-caption, HTML表格标题默认属性)
具有overflow 且值不是 visible 的块元素,
display: flow-root
column-span: all 应当总是会创建一个新的格式化上下文,即便具有 column-span: all 的元素并不被包裹在一个多列容器中。
BFC的特性
- 内部的Box会在垂直方向上一个接一个地放置
- Box垂直方向的距离由margin决定,属于同一个BFC的两个相邻Box的margin会发生重叠
- 在一个块级格式化上下文中父子元素的margin会发生重叠,内部元素自身的上下margin也会发生重叠
- BFC的区域不会与float box重叠
- BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素
- 计算BFC的高度时,浮动元素也参与计算
BFC的作用
- 解决margin合并问题
合并规则:- 两个margin都是正值的时候,取两者的最大值;
- 当 margin 都是负值的时候,取的是其中绝对值较大的,然后,从0位置,负向位移;
- 当有正有负的时候,先取出负 margin 中绝对值中最大的,然后,和正 margin 值中最大的 margin 相加。
- 解决父子合并问题:当父元素没有内容或内容在子元素的后面且没有内边距或没有边框时,子元素的上外边距将和父元素的上外边距合并为1个上外边距,且值为最大的那个上外边距,同时该上外边距作为父元素的上外边距。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JS Bin</title>
<style>
body{
background:red;
margin:20px;
}
div{
background:yellow;
margin:0px;
}
</style>
</head>
<body>
<div>
<p>haode</p>
</div>
</body>
</html>
给其父元素div中添加overflow:hidden来产生BFC即可将子元素的外边距包含进来。或者给父元素设置边框,则子元素的margin会被包含在父元素内,不会溢出。或者父元素display为inline-block等。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
》 <title>JS Bin</title>
<style>
body{
background:red;
margin:20px;
}
div{
background:yellow;
margin:0px;
overflow:hidden;
}
</style>
</head>
<body>
<div>
<p>haode</p>
</div>
</body>
</html>
- 解决同一个BFC下垂直方向上相邻元素外边距合并问题
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JS Bin</title>
<style>
body{
background:grey;
margin:20px;
}
.one{
background:yellow;
margin:20px;
}
.two{
background:white;
margin:20px;
}
</style>
</head>
<body>
<div class="one">haode</div>
<div class="two">haha</div>
</body>
</html>
此时两个div框之间的距离只有20px,也就是说两者的外边框发生了重合,为了解决这一问题,可以给其中一个元素添加父元素,并使其产生BFC,此时两个元素间的间距即为20px+20px。另外可以在上下两个元素间加一个空元素,display为table或flex,或增加一个0.1px的可以忽略的border。
<html>
<head>
<meta charset="utf-8">
<title>JS Bin</title>
<style>
body{
background:grey;
margin:20px;
}
.one{
background:yellow;
margin:20px;
}
.father{
overflow:hidden;
}
.two{
background:white;
margin:20px;
}
</style>
</head>
<body>
<div class="one">haode</div>
<div class="father">
<div class="two">haha</div>
</div>
</body>
</html>
- 元素自己合并也是同理,比如当该元素中没有内容时,其上下元素间的间距仅为上下两元素的外边距加上一半该元素的外边距值
- 清除环绕
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JS Bin</title>
<style>
.father{
width:200px;
height:200px;
background:grey;
}
.sonone{
float:left;
background:yellow;
}
.sonetwo{
background:red;
}
</style>
</head>
<body>
<div class="father">
<div class="sonone">好好学习</div>
<div class="sonetwo">天天向上aaaaaaaaaaaaaaaaaaaaa
</div>
</div>
</body>
</html>
将元素设置为BFC,即可清除环绕。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JS Bin</title>
<style>
.father{
width:200px;
height:200px;
background:grey;
}
.sonone{
float:left;
background:yellow;
}
.sonetwo{
background:red;
overflow:hidden;
}
</style>
</head>
<body>
<div class="father">
<div class="sonone">好好学习</div>
<div class="sonetwo">天天向上aaaaaaaaaaaaaaaaaaaaa
</div>
</div>
</body>
</html>