Block Formatting Context 能帮助我们做什么?

Block Formatting Context(块格式化上下文)是个很重要的概念,它决定了元素如何对其内容进行定位,以及与其他元素的关系和相互作用。

举个好理解的例子:可以把页面想象成一个社区,这个社区里的建筑就是 HTML 元素。而为了避免不同社区里的建筑相互混淆,开发商都是把建筑建在自己的社区里,这样的话无论开发商怎么盖楼,都不会影响到其它社区,那么这个社区的范围 就可以被想象成 Block Formatting Context。

由于在 IE8 之前的 IE 版本中,规范中没有提及 Block Formatting Context 的概念,而是用私有属性 hasLayout 来达到相似的目的。两者都是决定了对内容如何定位及大小计算的规则,以及与其它元素的相互作用的规则,但它们对一类事物的不同理解,以及它们的启用条件也 都不尽相同,所以很多兼容性的问题都是因它而起。

可生成 Block Formatting Context 的 CSS 特性:

  • float: ( 除 none 外的任何值 )
  • overflow: ( 除 visible 外的任何值 )
  • display: ( table-cell,table-caption 或 inline-block )
  • position: ( 除 relative 和 static 外任意值 )

可触发 hasLayout 的 CSS 特性:

  • display: inline-block
  • height: ( 除 auto 外任何值 )
  • width: ( 除 auto 外任何值 )
  • float: ( left 或 right )
  • position: absolute
  • writing-mode: tb-rl
  • zoom: ( 除 normal 外任意值 )

 

目前最好的解决方案就是使元素即生成 Block Formatting Context,又触发 hasLayout。IE下通过设置“zoom:1”,便可触发 hasLayout。

好了,讲了这么多概念性的东西,我们来看看 Block Formatting Context 能在实际中帮我们解决什么问题:

1.防止文字环绕

防止文字环绕

.red, 
.orange,
.yellow, 
.green { float:left; width:120px; height:120px; }
.red { background:red; }
.orange { background:orange; }
.yellow { background:yellow; }
.green { background:green; }
.w_1,
.w_2 { overflow:hidden; }
<div class="box"></div>
<ul class="news-list">
  <li>我是个测试数据,别管我 ^ ^</li>
  <li>我是个测试数据,别管我 ^ ^</li>
  <li>我是个测试数据,别管我 ^ ^</li>
  <li>我是个测试数据,别管我 ^ ^</li>
  <li>我是个测试数据,别管我 ^ ^</li>
  <li>我是个测试数据,别管我 ^ ^</li>
</ul>

overflow 属性一旦被指定,那么一个新的 Block Formatting Context 就被创建了,它不再围绕浮动元素。

猛击demo ☻

2.闭合浮动

闭合浮动

.red, 
.orange,
.yellow, 
.green { float:left; width:120px; height:120px; }
.red { background:red; }
.orange { background:orange; }
.yellow { background:yellow; }
.green { background:green; }
.w_1,
.w_2 { overflow:hidden; }
<div class="w_1">
  <div class="red"></div>
  <div class="orange"></div>
</div>
<div class="w_2">
  <div class="yellow"></div>
  <div class="green"></div>
</div>

本来想由四个方块组成一个两行两列的布局,但是由于 .red, .orange, .yellow, .green 这四个 div 同在一个布局环境中,即便通过 .w_1, .w_2 这两个 div 划分,浮动之后它们还会一个接一个的排列,并不会因为有 div 划分而换行。而给 .w_1, .w_2 两个 div 创建 Block Formatting Context 后,这四个 div 便两两划分到不同的布局环境之中,从而闭合浮动。

猛击demo ☻

3.阻止空白边折叠

阻止边距折叠

.box{ width:300px; margin-bottom:20px; border:1px solid #ccc; }
.div1{ background:#ccc; }
.div2{ margin:30px 0; width:150px; }
<div class="box">
  <div class="div1">
    <div class="div2">我没有开启bfc</div>
  </div>
</div>

div1的宽高都没有设置,它的宽度等于 box 的大小,高度等于 div2 的大小,当创建 Block Formatting Context 后,div1 和 div2 不再发生空白边折叠,深灰色的 div1 撑满了 box。

猛击demo ☻

4.包含块计算高度时加上浮动元素

contains_blocks_of_computing_height

.box{ width:300px; border:3px solid #000; }
.div1,
.div2,
.div3{ width:300px; height:30px; }
.div1{ background:#ccc; }
.div2{ background:#aaa; }
.div3{ float:left; background:#ddd; }
.bfc{ overflow:hidden; zoom:1; }
<div class="box bfc">
  <div class="div1"></div>
  <div class="div2"></div>
  <div class="div3">浮动元素</div>
</div>

普通流中的块级元素在进行高度计算时,浮动子元素不参与计算,当创建 Block Formatting Context 后,包含块计算高度时会加上浮动元素的高度。

猛击demo ☻

5.避免普通流中的块容器与浮动元素相互覆盖

avoid_covering_with_floating_elements

.box{ margin-bottom:60px; }
.div1{ float:left; width:80px; height:80px; background:#FFD700; filter:alpha(opacity=50); opacity: 0.5;}
.div2{ width:300px; height:60px; background:#018202; }
.bfc{ overflow:hidden; zoom:1; }
<div class="box">
  <div class="div1">浮动元素</div>
  <div class="div2 bfc">Block Formatting ContextBlock </div>
</div>

div1 是个浮动元素,有50%的透明度。div2 是个一般的块元素,当 div2 没有创建 Block Formatting Context 时,它会与浮动元素重叠,但创建 Block Formatting Context 后,便不会重叠了。

猛击demo ☻

6.三栏布局

layout_1

.div1,
.div2{ width:250px; }
.div1{ float:left; }
.div2{ float:right; }
.bfc{ overflow:hidden; zoom:1; }
<div class="div1">左浮动</div>
<div class="div2">右浮动</div>
<div class="div3 bfc"></div>

三栏布局,左右两栏浮动并且固定宽度,中间创建 Block Formatting Context 后自适应。

猛击demo ☻

7.两栏布局

layout_2

.div1,
.div2{ padding:10px; }
.div1{ float:left; width:200px; }
.bfc{ overflow:hidden; zoom:1; }
<div class="div1">Sidebar</div>
<div class="div2 bfc">main</div>

两栏布局,左边栏固定宽度,右边创建 Block Formatting Context 后自适应。

猛击demo

posted @ 2013-06-05 09:41  a fine day  阅读(120)  评论(0编辑  收藏  举报