Block Formatting Context

来自聚焦前端@任浩‘博客 http://www.focusweb.in/  

看到Block Formatting Context这个词语时,当时也是一头雾水,搜索了大量相关的资料后,对其有了一定的了解。对css的布局有了一个新的认识。

Block Formatting Context是要深入理解CSS的一个必须理解的概念。

简单地说,Block Formatting Context就是页面上的一个隔离的独立容器,容器里面的子元素不会在布局上影响到外面的元素,反之也是如此。不是所有的元素都会建立一个“Block Formatting Context“。只要符合条件,任何块级元素都建立一个新的”Block Formatting Context”, 一个” Block Formatting Context”至少满足以下条件之一。

  • float:left
  • float:right
  • position:absolute
  • display:inline-block
  • display:inline-table
  • display:table-cell
  • display:table
  • overflow:auto
  • overflow:scroll
  • overflow:hidden(也就是除了overflow:visible;)

Block Formatting Context怎样流动?

Block Formatting Context在文档流中属于正常流。也就是说,它跟块级模型、inline模型、盒模型的relative position、还有run in盒模型一样,属于页面文档流。

ps.与正常页面文档流相对应的,还有浮动和绝对定位(fixed是absolute的一个子集)。

Block Formatting Context有什么用?

1.Block Formatting Context可以阻止边距折叠(margin collapsing)。
我们知道在一般情况下,两个上下相邻的盒子会折叠它们垂直方向接触到的边距,这种情况只会发生在同一个Block Formatting Context中。换句话说,在同一个布局环境中(Block Formatting Context)是边距折叠的必要条件。这也就是为什么浮动的元素和绝对定位元素不会发生边距折叠的原因(当然还有很多种情况也不会折叠)。

2.Block Formatting Context可以包含内部元素的浮动
请run一下如下代码:

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4.  <meta charset="utf-8">
  5.  <title>Demo</title>
  6.  <style type="text/css">
  7.  html, body {
  8.    margin: 0;
  9.    padding: 0;
  10.  }    
  11.  </style>
  12. </head>
  13. <body>  
  14.  <div style="background:blue; overflow:hidden; *zoom:1">
  15.   <p style="float:left; margin:20px">段落一</p>
  16.  </div>
  17.  <div style="background:blue;">
  18.   <p style="float:left; margin:20px">段落二</p>
  19.  </div>
  20. </body>
  21. </html>

以上是两个同样的DIV,设置了背景色为蓝色,但后一个DIV的背景颜色没有显示出来,为内部的浮动元素脱离了文档流,不受父元素的控制,那么父元素在文档流中是一个空标签,没有高度和宽度,也就不显示任何颜色;而第二个div由于生成了Block Formatting Context(通过overflow:hidden;触发)会包容住里面的浮动元素,这样容器才会有自己的宽度和高度(被子元素撑开),这样就会显示出颜色。

3.Block Formatting Context可以阻止元素覆盖浮动盒模型
规范说:Block Formatting Context的盒模型border外延(而不是margin外延,也就是说无视margin设置)不会覆盖周围的浮动盒模型margin外延。这就是说浏览器应该默默创建一个特定边距来阻止Block Formatting Context的盒模型border外延覆盖周围的浮动盒模型。出于此种原因,接在浮动元素后面的Block Formatting Context上设置的负边距应该是无效的(应该被浏览器默默创建的特定边距覆盖),不过对此-webkit浏览器和IE6会有不正确的理解,试试用不同的浏览器看看这个页面,webkit和IE6理解是不正确的,其余是正确的。

原文请看:http://www.yuiblog.com/blog/2010/05/19/css-101-block-formatting-contexts

 


以上是博客原文。
补充: (from: http://rebuildpattern.com/node/44

下面分别介绍这3个性质。

性质一:Block Formatting Context会阻止边距折叠

This is a paragraph inside a DIV with a blue background, styled with
margin:20px
.

This is a paragraph inside a DIV with a blue background, styled with
margin:20px
.

This is a paragraph inside a DIV with a blue background, it is styled with
margin:20px
, The parent DIV is styled with
overflow:hidden;zoom:1
.

前两个div里面的p的垂直边距折叠成了一个,而第三个div由于生成了Block Formatting Context(通过overflow:hidden;触发),不会使相邻的边距折叠。

性质二:Block Formatting Context可以包含内部元素的浮动

This paragraph is a float inside a DIV with a blue background, it is styled with
margin:20px

This paragraph is a float inside a DIV with a blue background, it is styled with
margin:20px
. The parent DIV is styled with
overflow:hidden;zoom:1
.

This paragraph is a float inside a DIV with a blue background, it is styled with
margin:20px
. The parent DIV is styled with
overflow:hidden;zoom:1
.

 

 

 

 

三个div同样都是设置了背景色为蓝色,但前一个div就没有显示出来,因为内部的浮动元素脱离了文档流,不受父元素的控制,那么父元素在文档流中是一个空标签,没有高度和宽度,也就不显示任何颜色;而第二个div由于生成了Block Formatting Context(通过overflow:hidden;触发),会包容住里面的浮动元素,这样容器才会有自己的宽度和高度(被子元素撑开),这样就会显示出颜色;第三个div同样因为生成了Block Formatting Context(通过float:left;触发),显示出颜色。

性质三:Block Formatting Context可以阻止元素覆盖浮动盒模型

这是非常给力的一个特性。规范说:Block Formatting Context的盒模型border外延(而不是margin外延,也就是说无视margin设置)不会覆盖周围的浮动盒模型margin外延。这就是说浏览器应该默默创建一个特定边距来阻止Block Formatting Context的盒模型border外延覆盖周围的浮动盒模型。出于此种原因,接在浮动元素后面的Block Formatting Context上设置的负边距应该是无效的(应该被浏览器默默创建的特定边距覆盖),不过对此-webkit浏览器和IE6会有不正确的理解,试试用不同的浏览器看看这个页面,webkit和IE6理解是不正确的,其余是正确的。

.sideBar { background: skyBlue; float: left; width: 180px; }
.sideBar { background: yellow; float: right; width: 180px; }
#main { background: pink; overflow: hidden; zoom: 1; border: 5px solid teal; } 
 
 

由于此种特性是赋予在border外延而不是margin外延上,那么如果希望上面的Block Formatting Context(也就是有border的那个盒子)左右两边出现边距,那么只有两种方法:

  • 给Block Formatting Context设置一个超过两边浮动盒模型宽度的margin值,比如margin:0 220px;
  • 在浮动元素上设置20px margin

ps.前一种方法在Chrome和IE6下跟别的浏览器表现不一。后一种方法在IE6/7下会出现双边距bug。 ps.border外延跟一个盒模型有没有设置border属性完全没有关系,只是从盒模型上无视margin而已。 ps.the space that shows in IE6 between the pink box and the two floats is due to the three pixel jog bug.

hasLayout vs Block Formatting Context

你应该已经注意到了,上面的代码都是用overflow:hidden;*zoom:1来定义样式。这是因为这段代码为标准浏览器的对应盒模型生成了Block Formatting Context,为非标准的IE6/7则触发了hasLayout。hasLayout跟Block Formatting Context一样都可以阻止边距折叠、包含浮动元素、阻止元素覆盖浮动盒模型。 关于hasLayout,具体见hasLayout

你可能感兴趣的:(context)