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.防止文字环绕

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 就被创建了,它不再围绕浮动元素。


2.闭合浮动

Block Formatting Context 能帮助我们做什么?-图片-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 便两两划分到不同的布局环境之中,从而闭合浮动。


3.阻止空白边折叠

Block Formatting Context 能帮助我们做什么?-图片-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。


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

Block Formatting Context 能帮助我们做什么?-图片-4

.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 后,包含块计算高度时会加上浮动元素的高度。


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

Block Formatting Context 能帮助我们做什么?-图片-5

.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.三栏布局

Block Formatting Context 能帮助我们做什么?-图片-6

.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 后自适应。


7.两栏布局

Block Formatting Context 能帮助我们做什么?-图片-7

.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 后自适应。


参考:

《不能同时在 IE6 IE7 IE8(Q) 中触发 hasLayout 并在其他浏览器中创建 Block Formatting Context 的元素在各浏览器中的表现会有差异》

评论

*
*