本文章对BFC块格式上下文的含义,原理进行说明,并且附加常用的应用场景。
BFC特点:
属于BFC的元素 / 如何触发BFC:
display: flow-root
<html>
与<body>
标签以下是证明:
我们看一个默认的,没有任何样式的html文件,浏览器的用户代理样式表会给初始的body一个margin:8px
的默认样式。
body是html的子盒子,如果这两个都是正常盒子,根据外边距坍塌,body的上外边距会直接顶开,带着html盒子一起下移。但很明显以下事实告诉我们并不会这样。
可以看到<html>
标签并没有被顶开,因为html是一个BFC区域。
这里给出模拟<html>
和<body>
的两个普通盒子:
.c-html{
height: 200px;
width: 200px;
background-color:cornflowerblue
}
.c-body{
margin: 10px;
height: 100px;
width: 100px;
background-color:aquamarine
}
<body>
无法通过overflow:hidden
触发BFCW3C对BFC定义中有写到,html的overflow默认是visible,那么子元素body的overflow:hidden
被用于视口,overflow的扩散行为会导致body的overflow属性为visible,所以无法触发BFC。
只能把html元素的overflow设置为hidden之后,body设置hidden(此时body不会被用于视口)才会触发BFC。
在body内的非BFC元素盒子,上下外边距会重叠,会造成外边距垂直坍塌。
解决这个问题,也是依靠BFC。分别用两个BFC盒子包裹,由于BFC特性,两个盒子不会相互影响。
.box1{
margin: 20px;
height: 200px;
width: 200px;
background-color:gold;
}
.BFC{
overflow: hidden;
}
添加BFC包裹后:
父子盒子嵌套,给子盒子添加margin-top
,效果并非子盒子远离了父盒子的边框,而是带着父盒子偏离了上方。
解决方法:让父盒子触发BFC,比如让父盒子display: flow-root
变成一个独立的区域,不会影响外面的元素布局。
另外的解决方法:
当父盒子没有设定高度,子盒子使用了浮动时,父盒子没有内容撑开会发生高度坍塌。
解决方法:让父盒子触发BFC,不影响外部布局,强行包裹了子元素,让浮动元素也参与了高度计算。
既然触发BFC可以清除浮动,那为何一般使用最多的是
overflow:hidden
?
BFC都可以清除浮动,但是如果用float或者position的方式清除浮动,这样会导致父元素本身脱离文档流,又会继续影响父元素的兄弟盒子或者更上的父元素。如果是flex的方式的BFC,那么父元素内部的浮动就会消失。
选择overflow:hidden
,或者是伪元素清除浮动,实现BFC的代价会更小。
当盒子A和盒子B在同一行时,如果盒子B浮动会覆盖标准流元素。
但当盒子A触发了BFC,那么浮动的盒子B不能覆盖A,此时盒子A会占据除了B之外的整行。可以利用这个特性,实现盒子A根据盒子B的宽度来做自适应。
原因就是浮动的B本来是BFC盒子,当A也变成BFC之后,就完全不会相互影响了。
.box1{
height: 200px;
width: 200px;
float: left;
background-color:gold;
}
.box2{
height: 300px;
background-color: chartreuse;
}
.BFC{
overflow: hidden;
}
创建BFC区域
设置overflow:hidden
变成BFC盒子,但是副作用是会隐藏溢出的元素显示。
良好的创建方式
使用display: flow-root
会直接创建新的BFC。相比于其他的方法,flow-root更兼容浏览器,运行更稳定。
额外标签
在浮动元素的末尾添加一个空的标签,并且设置clear属性(这个标签必须是块元素)
after伪元素
实现的原理与额外标签一致,只是用伪元素替代了具体的标签。没有增加标签,也没有隐藏影响,副作用更小。