块格式化上下文(block formatting context)
无意间发现这个东西,看了下MDN发现这个东西跟布局有点关系;
MDN上的介绍:
块格式化上下文(block formatting context)是页面 CSS 视觉渲染的一部分,它是用于决定块盒子的布局及浮动相互影响的一个区域。
我的理解是BFC 是页面渲染中其中的一种机制,这种机制会影响着元素的定位以及与其兄弟元素之间的相互作用;
如何触发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会发生重叠;
- 每个元素的margin box的左边, 与包含块border box的左边相接触(对于从左往右的格式化,否则相反),即使存在浮动也是如此;
- BFC的区域不会与float box重叠;
- BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素,反之也如此;
- 计算BFC的高度时,浮动元素也参与计算;
BFC作用以及一些Demo
防止垂直 margin 重叠
根据第二条规则:
1 <!DOCTYPE html> 2 <html> 3 <head lang="en"> 4 <meta charset="UTF-8"> 5 <title></title> 6 <style> 7 *{margin: 0px;padding: 0px} 8 p { 9 color: red; 10 background: #fcc; 11 width: 100px; 12 height: 100px; 13 line-height: 100px; 14 text-align: center; 15 margin: 50px; 16 border: solid 1px red; 17 } 18 /*.div1 {*/ 19 /*overflow: hidden;*/ 20 /*border: solid 1px red;*/ 21 /*}*/ 22 </style> 23 </head> 24 <body> 25 <p>Haha</p> 26 <p>Hehe</p> 27 <!--<div class="div1">--> 28 <!--<p>Hehe</p>--> 29 <!--</div>--> 30 </body> 31 </html>
很明显margin重叠了,根据如上所速,我们要让他渲染成为不同的BFC;一开始做如下修改:
<p class="pp">Hehe</p>
.pp{overflow: hidden;}
运行发现不行,后来在看仔细看BFC布局规则,根据第2条规则,这两个p都是在跟元素(我这里理解是body)的BFC中,所以无法阻止重叠,修改代码如下:
1 <!DOCTYPE html> 2 <html> 3 <head lang="en"> 4 <meta charset="UTF-8"> 5 <title></title> 6 <style> 7 *{margin: 0px;padding: 0px} 8 p { 9 color: red; 10 background: #fcc; 11 width: 100px; 12 height: 100px; 13 line-height: 100px; 14 text-align: center; 15 margin: 50px; 16 border: solid 1px red; 17 } 18 .div1 { 19 overflow: hidden; 20 border: solid 1px red; 21 } 22 23 </style> 24 </head> 25 <body> 26 <p>Haha</p> 27 28 <div class="div1"> 29 <p>Hehe</p> 30 </div> 31 </body> 32 </html>
这样第二个p 不仅生成了BFC,并且与第一个BFC是不同的,所以阻止了重叠问题;
BFC 包含浮动元素
我们经常使用浮动来布局,这种情况下容器元素没有高度并且其浮动子元素脱离了网页的常规流。我们通常用清除浮动解决这个问题,最普遍的做法就是使用伪元素,但我们也可以通过创建一个BFC来解决问题 代码如下:
1 <!DOCTYPE html> 2 <html> 3 <head lang="en"> 4 <meta charset="UTF-8"> 5 <title></title> 6 <style> 7 *{margin: 0;padding: 0;} 8 .content{ width: 400px;border: solid 1px red;overflow: hidden } 9 .div1{ width: 100px;height: 100px;background-color: #003300; float: left} 10 </style> 11 </head> 12 <body> 13 <div class="content"> 14 <div class="div1">this is div1</div> 15 <div class="div1">this is div2</div> 16 </div> 17 </body> 18 </html>
这样父元素就有高度了,float 造成的父元素高度不在坍塌;
使用BFC避免文字环绕
有时候浮动DIV旁边的文本会环绕它,有时候我们并不想这样这时,可以用BFC来解决,如下是未添加BFC代码:
1 <!DOCTYPE html> 2 <html> 3 <head lang="en"> 4 <meta charset="UTF-8"> 5 <title></title> 6 <style> 7 *{margin: 0;padding: 0;} 8 .floated{width: 50px;height: 50px;background-color: #003300;float: left} 9 .describe{width: 200px;} 10 </style> 11 </head> 12 <body> 13 14 <div class="container"> 15 <div class="floated"> 16 float div 17 </div> 18 <p class="describe"> 19 Quae hic ut ab perferendis sit quod architecto, 20 dolor debitis quam rem provident aspernatur tempora 21 expedita. 22 </p> 23 </div> 24 </body> 25 </html>
效果如图:
添加BFC之后代码如下:
1 <!DOCTYPE html> 2 <html> 3 <head lang="en"> 4 <meta charset="UTF-8"> 5 <title></title> 6 <style> 7 *{margin: 0;padding: 0;} 8 .floated{width: 50px;height: 50px;background-color: #003300;float: left} 9 .describe{width: 200px;overflow: hidden} 10 </style> 11 </head> 12 <body> 13 14 <div class="container"> 15 <div class="floated"> 16 float div 17 </div> 18 <p class="describe"> 19 Quae hic ut ab perferendis sit quod architecto, 20 dolor debitis quam rem provident aspernatur tempora 21 expedita. 22 </p> 23 </div> 24 </body> 25 </html>
效果如图:
总结
以上的几个例子都体现了BFC布局规则第五条:
BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素,反之也如此;
因为BFC
内部的元素和外部的元素绝对不会互相影响,因此, 当BFC
外部存在浮动时,它不应该影响BFC
内部Box的布局,BFC
会通过变窄,而不与浮动有重叠。同样的,当BFC
内部有浮动时,为了不影响外部元素的布局,BFC
计算高度时会包括浮动的高度。避免margin重叠也是这样的一个道理。