BFC
1. 什么是BFC
BFC,英文名 Block formatting context,直译为“块级格式化上下文”。它是W3C CSS 2.1规范中的一个概念,决定了元素如何对内容进行定位,以及与其他元素的关系和相互作用。
2.BFC元素所具有的特性
- 1.在同一个BFC内的两个相邻块级元素的外边距会重叠,但不同 BFC外边距不会重叠
- 2.在计算BFC高度时,将它内部的浮动元素也包含在内。
- 3.BFC的区域不会与外部浮动元素重叠
它是一个独立的渲染区域,只有Block-level box参与, 它规定了内部的Block-level Box如何布局,并且与这个区域外部毫不相干。(白话文: 孩子在家里愿意怎么折腾都行,但是出了家门口,你就的乖乖的,不能影响外面的任何人。)
3.如何创建BFC
MDN CSS developer guide 给出创建BFC的方法常用的有以下几种:
- 1、 根元素
- 2、 float属性不为none
- 3、 position为absolute或fixed
- 4、 overflow的值不为visible
- 5、 display的值为table-cell,table-caption,inline-block中的任何一个。
- 6、弹性元素(display为 flex 或 inline-flex元素的直接子元素)
另外: 匿名表格单元格元素(元素的 display为 table等)
4.BFC的应用场景
1. 解决块级元素垂直方向的边距重叠问题
由于块级元素垂直方向的边距会发生重叠,div间距并不是50px+100px,而是100px(较大的margin值)。
<style>
.top {
background-color: blue;
width: 100px;
height: 100px;
margin-bottom: 50px;
}
.bottom {
height: 100px;
width: 100px;
margin-top: 100px;
background-color: #ccc;
/* display: flex; */
/* overflow: hidden; */
}
</style>
<div class="main">
<div class="top"></div>
<div class="bottom"></div>
</div>
原因是因为,它们属于同一个BFC(根元素),外边距是会重叠滴。所以只要将它们其中一个属于另一个BFC,就可以啦。
<div class="main">
<div class="top"></div>
<div style="overflow: hidden;">
<div class="bottom"></div>
</div>
</div>
2.解决元素浮动后发生重叠的问题(自适应布局)
右边自适应布局
如图,左边的元素浮动之后,由于脱离标准文档流叠在了右边的元素上,为了让两个元素不重叠,我们把右边的元素设置成BFC:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
.left {
background-color: blue;
width: 100px;
height: 80px;
float: left;
}
.content {
height: 100px;
background-color: #ccc;
/* display: flex; */
/* display: table-cell;
width: 9000px; */
overflow: hidden;
}
</style>
</head>
<body>
<div class="main">
<div class="left"></div>
<div class="content">
start,nt,content,content,content,end.....
</div>
</div>
</body>
</html>
一个右边自适应的布局就完成了。
中间自适应布局
同理,我们可以搞一个中间自适应布局,代码如下(注意left和right盒子的位置)
<body>
<style>
.left {
background-color: blue;
width: 100px;
height: 80px;
float: left;
}
.right {
background-color: pink;
width: 100px;
height: 80px;
float: right;
}
.content {
height: 100px;
background-color: #ccc;
/* display: flex; */
overflow: hidden;
}
</style>
<div class="main">
<div class="left"></div>
<div class="right"></div>
<div class="content">
start,nt,content,content,content,end.....
</div>
</div>
</body>
3.清除浮动
overflow: hidden
清除浮动(计算BFC浮动元素高度)
1.如下代码,
<body>
<style>
.main {
border: 1px solid red;
}
.content {
height: 100px;
width: 100px;
background-color: #ccc;
float: left;
}
</style>
<div class="main">
<div class="content"></div>
</div>
</body>
子元素浮动后,父元素失去了高度,为了清除浮动带来的这个影响可以将父元素设置成一个BFC:
.main {
border: 1px solid red;
overflow: hidden;
}
这是因为在计算BFC高度时,将它内部的浮动元素也包含在内。
缺点:会导致溢出隐藏。
2.clear:both
清除浮动
常规的解决方法就是利用clear来清除浮动
<div class="main">
<div class="content"></div>
<div style="clear: both;"></div>
</div>
缺点: 添加许多无意义的标签,结构化较差。
3.利用伪元素和BFC清除浮动
用法:直接应用在父元素上就行。
1.使用after伪元素清除浮动
.clearfix::before, .clearfix::after {
content: '';
display: block;
height: 0;
/* font-size: 0; */
visibility: hidden;
clear: both;
}
.clearfix {
*zoom: 1;
}
2.使用双伪元素清除浮动
这是bootstrap上使用的方法。
.clearfix::before,
.clearfix::after {
content: '';
display: table;
/* font-size: 0; */
}
.clearfix::after {
clear: both;
}
.clearfix {
*zoom: 1;
}
解析:
- :after伪类在元素末尾插入了一个包含空格的字符,并设置display为table
- display:table会创建一个匿名的table-cell,从而触发块级上下文(BFC),因为容器内float的元素也是BFC,由于BFC有不能互相重叠的特性,并且设置了clear: both,:after插入的元素会被挤到容器底部,从而将容器撑高。并且设置display:table后,content中的空格字符会被渲染为0*0的空白元素,不会占用页面空间。
- content包含一个空格,是为了解决Opera浏览器的BUG。当HTML中包含contenteditable属性时,如果content没有包含空格,会造成清除浮动元素的顶部、底部有一个空白(设置
font-size:0
也可以解决这个问题)。 - :after伪类的设置已经达到了清除浮动的目的,但还要设置:before伪类,原因如下
- :before的设置也触发了一个BFC,由于BFC有内部布局不收外部影响的特性,因此:before的设置可以阻止margin-top的合并。(我试了没效果…)
- 这样做,其一是为了和其他清除浮动的方式的效果保持一致;其二,是为了与ie6/7下设置zoom:1后的效果一致(即阻止margin-top合并的效果)。
- zoom: 1用于在ie6/7下触发haslayout和contain floats
总结
清除浮动的方式 | 优点 | 缺点 |
---|---|---|
额外标签法(隔墙法) | 通俗易懂,书写方便 | 添加许多无意义的标签,结构化较差。 |
父级overflow:hidden; | 书写简单 | 溢出隐藏 |
父级after伪元素 | 结构语义化正确 | 由于IE6-7不支持:after,兼容性问题 |
父级双伪元素 | 结构语义化正确 | 由于IE6-7不支持:after,兼容性问题 |
注:现在较少考虑IE低版本的兼容性