块级格式上下文
什么是BFC
全称Block Formatting Context,简称BFC
它是一块独立的渲染区域,它规定了在该区域中,常规流块盒的布局
- 注意是
常规流块盒
(所以并不包含行盒)- 常规流块盒在水平方向上,必须撑满包含块;
- 常规流块盒在包含块的垂直方向上依次摆放;
- 常规流块盒若外边距无缝相邻,则进行外边距合并;
- 常规流块盒的自动高度和摆放位置,会无视浮动、绝对定位、固定定位等脱离常规流的元素。
BFC渲染区域:
- 这个区域是由某个HTMl元素创建,以下元素会在其内部创建BFC区域
- 根元素:意味着,元素创建的BFC元素,覆盖了网页中所有的元素
- 浮动和
position
属性值不为static和relative的定位元素
- 块级元素具有
overflow
且值不等于visible
的块盒 - 非块级元素具有
display: inline-block
,table-cell
,table-caption
,flex
,inline-flex
到这里会有了一个疑问:为什么dispay:inline-block
也会触发BFC呢?
通过查阅资料和咨询老师,得出来下面结论:
- 其实html中的元素从根上分类就只有两种
行内级元素
和块级元素
,这种分类按照我的理解就是根据元素在外部表现的不同而进行分类的。- 那么像
display:inline-block
之类的属性,会使元素在外部表现为行内元素的特点,而在内部表现为块级元素的特点,所以在内部也会触发BFC的渲染区域
— 以上纯属是我的个人见解
接下来回到BFC的讨论上。我们先看下图
通过下图我们可以很清楚的理解BFC的概念(在元素内部创建的独立渲染区域)
那么什么是独立的
?
- 我们以这样理解:
- 不同的BFC区域,它们进行渲染时是互不干扰的
- 创建BFC的元素,隔绝了它内部和外部的联系,内部的渲染不会影响外部
BFC规则及用途
接下来了解一下BFC的规则,也可以说是BFC在实际中的应用
- 具体规则
- 创建BFC的元素,它的自动高度需要计算浮动元素
- 创建BFC的元素,它的边框不会与浮动元素重叠
- 创建BFC的元素,不会和它的子元素进行外边距合并
1、我们先来解读第一条规则:创建BFC的元素,它的自动高度需要计算浮动元素
<div class="box">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
.box{
background-color: chartreuse;
}
.item{
float:left;
width:200px;
height:200px;
margin:20px;
background-color: chocolate;
}
通过以上代码我们让父元素造成高度坍塌,如下图:
那么我们以前解决高度塌陷的方法是通过给父元素添加一个空的兄弟元素,并且添加clear:both属性清除浮动
但是学习了BFC之后,我们可以让父元素创建BFC
.box{
background-color: chartreuse;
/* position: absolute;
float: left; */
overflow: hidden;
}
我们可以看到父元素的高度回来了,并且高度由子元素撑开,这就实现了父元素的高度自适应。由于浮动和绝对定位会使元素脱离常规流,从而影响布局,所以我们常用的创建BFC的方法是overflow:hidden
2、创建BFC的元素,它的边框不会与浮动元素重叠
<div class="float"></div>
<div class="box"></div>
.float{
float: left;
width:200px;
height:200px;
margin:20px;
background-color: cornflowerblue;
}
.box{
background-color: chartreuse;
height:500px;
}
因为我们的box
盒子是块级元素,所以宽度会撑满父元素。
由于float
盒子浮动后,所以它本身的位置就会空出来
但是我们并不想让box
和float
重叠。
那么此时就可以给box
创建BFC,此时情况如下图:
创建了BFC的元素会自动避开浮动元素
但是我们给浮动元素设置了属性
margin:20px
,所以box避开的的是浮动元素的所有部分(包括margin),那么,通过这种情况,我们可以进行布局主内容部分的宽度自适应布局
3、创建BFC的元素,不会和它的子元素进行外边距合并
margin的重叠和传递
在实际项目中是比较常见的一个问题,因此,我们一般都需要对此进行消除,此时,我们可以通过创建BFC来解决这两个问题
- 1)margin的传递
<div class="box">
<div class="item"></div>
</div>
.box{
background-color: chartreuse;
width:500px;
height:500px;
margin:50px auto;
/*overflow:hidden;*/
}
我们可以看到第一个图是没有给父元素添加overflow:hidden
属性时的结果,而第二张图是创建了BFC的结果,对比两张图,我们可以很清晰的看到,子元素的margin-top本来是传递给了父元素,随后父元素创建了BFC后,子元素的margin-top没有在传递
- 2)margin的重叠
<div class="container">
<div class="box"></div>
</div>
<div class="container">
<div class="item"></div>
</div>
.box{
background-color: chartreuse;
width:200px;
height:200px;
margin-bottom: 50px;
/* overflow: hidden; */
}
.item{
margin-top: 20px;
height:200px;
width:200px;
background-color: crimson;
margin-top: 50px;
}
.container{
overflow: hidden;
}
我们可以看到第一个图,虽然我们同同时给两个元素设置了margin,但是却只生效了一个(较大值),两个元素的上下margin重叠了。当我们给他们的父元素添加overflow:hidden
属性后,我们就看到了第二张图,对比两张图,我们可以很清晰的看到,两个子元素的margin本来是重叠的,随后它们父元素创建了BFC后,子元素的margin就没有在重叠了。