首页 > 代码库 > 有关对hasLayout和BFC(Block Formatting Contexts)的理解

有关对hasLayout和BFC(Block Formatting Contexts)的理解

    2014年1月26日

   

    首先,hasLayout 和 Block Formatting Contexts 分别是什么?


    1、hasLayout是IE内部的一个特有的隐形属性,属性值为true/false。元素一旦拥有了这个属性,就拥有了布局,也就是说该元素可以对自己及其子元素进行尺寸计算和定位(比起依赖父元素进行布局会花费更大的代价)。由于这个元素是隐形的,不能通过CSS来设置hasLayout:true/false;可以通过js来检测元素是否拥有布局。hasLayout是只读属性,一旦触发,不可逆转。有些元素本身就默认拥有布局,有的元素可以通过一些CSS属性设置(如displaywidthheight等)来激发产生布局。并不是所有元素都拥有布局的原因是为了简洁和提高性能,拥有布局会消耗内存,并不轻量,会降低性能。最常用的是在CSS中设置zoom:1;来激发布局,不会产生任何其他影响的情况下让元素拥有布局。
 
   2、BFC(块级格式化上下文)就是一种属性,该属性会影响着元素的定位和与其兄弟元素之间的相互作用。拥有BFC的元素可以看成是被隔离了的独立的容器,容器里面的元素在布局上不会影响到容器外面的元素,它是属于普通流(在CSS 2.1中有三种定位方案:普通流、浮动、绝对定位)的,因此不会对兄弟元素产生影响。
 
那么,怎么触发hasLayout 和 BFC ?
   1、那些元素本身就拥有layout:
  • Images
  • Tables, TableRows, TableCells
  • HR
  • Input elements: text, button, file, select
  • Marquee
  • Framesets, Frames
  • Objects, applets, plugins
  • Absolute positioned elements
  • Floated elements
  • Inline-block elements
  • Filters (rotation, dropshadow, etc.)
  • Body (as well as HTML element in strict mode)
   2、哪些元素能够获得layout?
  • 在strict mode下,指定width或height的块级元素。
  • 兼容模式下, 指定了widht或height的任何元素
  • 设定了zoom属性的元素
  • 可编辑状态下的元素
  • 拥有viewlink行为的元素
  • 元素的Layout-flow属性跟父元素的不同(rtl to ltr)
   3、怎么触发BFC?
   满足下面任一条件的元素,会触发为 BFC :
  • 浮动元素,float 除 none 以外的值
  • 绝对定位元素,position(absolute,fixed)
  • display 为以下其中之一的值 inline-blocks,table-cells,table-captions
  • overflow 除了 visible 以外的值(hidden,auto,scroll)

但是,"display:table" 本身并不产生 BFC,而是由它产生匿名框,匿名框中包含 "display:table-cell" 的框会产 BFC。 总之,对于 "display:table" 的元素,产生 BFC 的是匿名框而不是 "display:table"。

在 CSS3 中,BFC 叫做 Flow Root,并增加了一些触发条件:

  • display 的 table-caption 值
  • position 的 fixed 值,其实 fixed 是 absolute 的一个子类,因此在 CSS2.1 中使用这个值也会触发 BFC ,只是在 CSS3 中更加明确了这一点。
然后,hasLayout 和 BFC 都有什么特性呢?
 
    1、hasLayout
  • 它会将元素限制在一个矩形的盒子内,从而保证元素的内容不会分散到另一个盒子周围,例如,在IE引擎中,一个拥有布局边框的元素不会环绕相邻的浮动元素。这点很重要,在很多地方都用到,例如人人、微博、留言等左边的头像用浮动,右边的内容让其拥有布局。
  • 由于Layout使得浏览器渲染引擎要额外地在内存中调用算法来计算元素尺寸和方位,所以它并不轻量,它会消耗更多的内存,并可能导致性能的下降。
  • 会产生元素无法自适应大小的副作用,一个拥有Layout的元素不会“自动缩小”来适应其子元素,例如,一个绝对定位具有Layout的盒模型如果有一个拥有Layout的子元素,它是不会自动缩小来适应这个子元素的尺寸的。
  • 而一个拥有Layout的盒模型会被子元素给撑开(IE6下的heigh bug)
  • 人们通常利用Layout来解决IE6bug,特别是与相对定位元素有关的,但实际上,相对定位元素不需要拥有Layout,如果让它们拥有Layout在一些情况下反而会产生问题。
  • 如果一个元素拥有了布局,并且设置displayinline;那么它实际上跟设置了displayinlin-block;效果一样。

    2、BFC

      (1)、BFC会阻止外边距折叠

       两个相连的div的垂直方向的外边距会折叠,前提是这两个div在同一块级格式上下文中(这点有人认为是CSS的bug,但更好的解释是把它看成是CSS的一个特性,之前竟然一直没注意到这点==、),要阻止外边距折叠,让父元素创建BFC,这样其子元素就不会与父元素产生外边距折叠的情况。

    (2)、BFC可以包含浮动的元素

      这个地方主要是闭合浮动的原理。在CSS中设置overflow:hidden/auto;来触发BFC以防止父元素的高度塌陷。例如 (这里的元素都没设置固定高)有一个div的父元素,其子元素浮动布局,这样子元素就脱离了文档流,父元素div就相当于一个空标签,发生了高度塌陷。利用overflow:hidden/auto;激发BFC,让其可以包含浮动元素,闭合浮动。

    (3)、BFC可以阻止元素被浮动元素覆盖

    浮动元素的块级兄弟元素会无视浮动元素的位置,尽量占满一整行,这样就会被浮动元素覆盖,为该兄弟元素触发 BFC 后可以阻止这种情况的发生。值得注意的是,假设浮动元素宽度和它的非浮动兄弟元素宽度都没有超过父元素宽度,但两个元素的宽度加起来超出了父元素宽度的时候,非浮动元素会下降到下一行,即处于浮动元素下方。

    hasLayout 和 BFC ? 

    其实hasLayout 和 BFC 的功能是相似的,只是hasLayout是用来处理IE bug的,所以在实际的开发过程中,为了兼容各个浏览器,在代码方面,.bj {zoom:1;overflow:hidden;}这部分可写到css的公共文件中,哪个地方用到了就添加此class。

 

        

       上述部分内容参考:http://kayosite.com/block-formatting-contexts-in-detail.html

 

                                http://www.cnblogs.com/yilian/