情景:浮动的高度塌陷时,使用overflow:hidden可以使父元素将浮动的子元素包含起来,解决问题。但背后的原理是什么?这就是今天要谈的BFC。css
在将BFC以前须要先了解几个概念: html
盒子模型(Box model):相信这个你们已经很了解了,这里就不详细说了。详见《CSS权威指南》 ide
块级元素:布局
Block-level elements are those elements of the source document that are formatted visually as blocks (e.g., paragraphs). The following values of the 'display' property make an element block-level: 'block', 'list-item', and 'table'.学习
即块级元素是源文档中被格式化为块(block)的元素,或者display属性为:'block', 'list-item', and 'table'的元素。flex
块级盒:ui
Block-level boxes are boxes that participate in a block formatting context. Each block-level element generates a principal block-level box that contains descendant boxes and generated content and is also the box involved in any positioning scheme.spa
块级盒主要存在于BFC中,每一个块级元素会产生主要的块级盒,该盒包含其子框和生成的内容,同时会受到不一样定位方案的影响。code
块容器盒orm
Except for table boxes, and replaced elements,a block-level box is also a block container box. A block container box either contains only block-level boxes or establishes an inline formatting context and thus contains only inline-level boxes. Not all block container boxes are block-level boxes: non-replaced inline blocks and non-replaced table cells are block containers but not block-level boxes. Block-level boxes that are also block containers are called block boxes.
除了表格框和替换元素,其余的块级盒都是块容器盒,块容器盒要么只包含块级盒,要么创建一个IFC(内行格式化上下文),并非全部的块容器盒都是块级盒:非替代inline-block和非替代table cells是块容器盒但不是块级盒。既是块级盒又是快容器盒的叫作块盒。
一下是块级盒、块盒和块容器盒三者的关系
正常流:不管是块级盒或者是行内盒在正常流都属于格式化上下文,块级盒存在于BFC,行内盒存在于IFC,因此,正常流格式化上下文中包含BFC和IFC(行内格式化上下文,另外一种格式化上下文)。
BFC(Block formatting contexts):顾名思义块级格式化上下文。通俗的说,它是一个独立的渲染区域,里面只有Block-level box,并规定他们的布局方式,与其余区域互不影响。
根元素或其它包含它的元素
浮动 (元素的 float 不为 none)
绝对定位元素 (元素的 position 为 absolute 或 fixed)
行内块 inline-blocks (元素的 display: inline-block)
表格单元格 (元素的 display: table-cell,HTML表格单元格默认属性)
表格标题 (元素的 display: table-caption, HTML表格标题默认属性)
overflow 的值不为 visible的元素
弹性盒子 flex boxes (元素的 display: flex 或 inline-flex)
内部的Box会在垂直方向,一个接一个地放置
Box垂直方向的距离由margin决定。属于同一个BFC的两个相邻Box的margin会发生重叠。若是相邻有一个是BFC的话,则BFC里面的子元素margin与外面的Box的margin不重叠。
每一个元素的margin box的左边, 与包含块border box的左边相接触(对于从左往右的格式化,不然相反)。即便存在浮动也是如此。
BFC的区域不会与float box重叠,经常使用来清除浮动和布局。
BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。
计算BFC的高度时,浮动元素也参与计算
1.防止margin值重叠(布局规则2)
举个例子:
<!DOCTYPE html> <html> <head> <title>BFC</title> <meta charset="utf-8"> <link rel="stylesheet" type="text/css" href="index.css"> </head> <body> <div class="red"></div> <div class="black"></div> </body> </html>
body{padding:0;margin:0} .red{ background:red ; width:200px; height: 200px; margin: 10px; } .black{ background:black ; width:200px; height: 200px; margin: 10px; }
结果margin重叠:
让红色方块变成BFC后:
<!DOCTYPE html> <html> <head> <title>BFC之防止margin重叠</title> <meta charset="utf-8"> <link rel="stylesheet" type="text/css" href="index.css"> </head> <body> <div class="wrap"> <div class="red"></div> </div> <div class="black"></div> </body> </html>
body{padding:0;margin:0} .red{ background:red ; width:200px; height: 200px; margin: 10px; } .wrap{overflow: hidden;} .black{ background:black ; width:200px; height: 200px; margin: 10px; }
结果margin不重叠
2.清除浮动
父元素包含浮动子元素(所有)时,高度会出现坍塌。
<!DOCTYPE html> <html> <head> <title>BFC</title> <meta charset="utf-8"> <link rel="stylesheet" type="text/css" href="index.css"> </head> <body> <div class="wrap"> <div class="red"></div> <div class="black"></div> </div> </body> </html>
body{padding:0;margin:0} .wrap{ width: 500px; border: blue solid 2px; } .red{ border: red solid 1px; width:200px; height: 200px; float: left; } .black{ border: black solid 1px; width:200px; height: 200px; float: right; }
结果:
给父元素添加overflow: hidden;
后父元素变成BFC,根据布局规则6,父元素会将子元素包含在内。
<!DOCTYPE html> <html> <head> <title>BFC</title> <meta charset="utf-8"> <link rel="stylesheet" type="text/css" href="index.css"> </head> <body> <div class="wrap"> <div class="red"></div> <div class="black"></div> </div> </body> </html>
body{padding:0;margin:0} .wrap{ width: 500px; border: blue solid 2px; overflow: hidden; } .red{ border: red solid 1px; width:200px; height: 200px; float: left; } .black{ border: black solid 1px; width:200px; height: 200px; float: right; }
结果
3.两栏自适应布局
若是左栏设置为浮动,右边一栏正常显示,则会将浮动会盖住右边。
 l> <html> <head> <title>BFC</title> <meta charset="utf-8"> <link rel="stylesheet" type="text/css" href="index.css"> </head> <body> <div class="left"></div> <div class="main"></div> </body> </html>
body{padding:0;margin:0} .left{ border: red solid 1px; width:200px; height: 200px; float: left; } .main{ border: black solid 1px; width:250px; height: 250px; }
结果
给main那一栏添加 overflow: hidden;
后变成BFC(根据布局规则2)。
<!DOCTYPE html> <html> <head> <title>BFC</title> <meta charset="utf-8"> <link rel="stylesheet" type="text/css" href="index.css"> </head> <body> <div class="left"></div> <div class="main"></div> </body> </html>
body{padding:0;margin:0} .left{ border: red solid 1px; width:200px; height: 200px; float: left; } .main{ border: black solid 1px; width:250px; height: 250px; overflow: hidden; }
结果
由于根元素就是一个BFC,文档中块级盒的布局规则符合BFC,因此书里面写的文档流是从上到下的排列、相邻块级之间的margin会发生重叠,浮动会自动造成block等知识点,其实在这里就能找到答案。包括清除浮动、两栏自适应布局的原理也清晰明了。所以掌握BFC原理也掌握另外一种解决问题的思路。
这里有点建议就是尽可能阅读官网的资料,里面的内容最准确,最权威。
以上是我粗浅的理解,若是哪里有问题,请帮忙指出,有未涉及的知识点,欢迎补充。一块儿学习,共同进步。
https://www.w3.org/TR/2011/RE...