情景:浮动的高度塌陷时,使用overflow:hidden可使父元素将浮动的子元素包含起来,解决问题。但背后的原理是什么?这就是今天要谈的BFC。
在将BFC之前需要先了解几个概念:
盒子模型(Box model):相信这个大家已经很了解了,这里就不详细说了。详见《CSS权威指南》
块级元素:
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'的元素。
块级盒:
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.
块级盒主要存在于BFC中,每个块级元素会产生主要的块级盒,该盒包含其子框和生成的内容,同时会受到不同定位方案的影响。
块容器盒
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,并规定他们的布局方式,与其他区域互不影响。
BFC的生成
根元素或其它包含它的元素
浮动 (元素的 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)
BFC布局规则
内部的Box会在垂直方向,一个接一个地放置
Box垂直方向的距离由margin决定。属于同一个BFC的两个相邻Box的margin会发生重叠。如果相邻有一个是BFC的话,则BFC里面的子元素margin与外面的Box的margin不重叠。
每个元素的margin box的左边, 与包含块border box的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此。
BFC的区域不会与float box重叠,常用来清除浮动和布局。
BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。
计算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.两栏自适应布局
如果左栏设置为浮动,右边一栏正常显示,则会将浮动会盖住右边。
![clipboard.png](/img/bVHIZZ)
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...