视觉格式化模型之BFC

2017-01-05 11:04:46来源:作者:SegmentFault人点击

情景:浮动的高度塌陷时,使用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的话,则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...

https://developer.mozilla.org...

http://www.yangyong.me/css2-b...

最新文章

123

最新摄影

微信扫一扫

第七城市微信公众平台