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

    2014年1月26日css

   

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


    一、hasLayout是IE内部的一个特有的隐形属性,属性值为true/false。元素一旦拥有了这个属性,就拥有了布局,也就是说该元素能够对本身及其子元素进行尺寸计算和定位(比起依赖父元素进行布局会花费更大的代价)。因为这个元素是隐形的,不能经过CSS来设置hasLayout:true/false;能够经过js来检测元素是否拥有布局。hasLayout是只读属性,一旦触发,不可逆转。有些元素自己就默认拥有布局,有的元素能够经过一些CSS属性设置(如displaywidthheight等)来激发产生布局。并非全部元素都拥有布局的缘由是为了简洁和提升性能,拥有布局会消耗内存,并不轻量,会下降性能。最经常使用的是在CSS中设置zoom:1;来激发布局,不会产生任何其余影响的状况下让元素拥有布局。
 
   二、BFC(块级格式化上下文)就是一种属性,该属性会影响着元素的定位和与其兄弟元素之间的相互做用。拥有BFC的元素能够当作是被隔离了的独立的容器,容器里面的元素在布局上不会影响到容器外面的元素,它是属于普通流(在CSS 2.1中有三种定位方案:普通流、浮动、绝对定位)的,所以不会对兄弟元素产生影响。
 
那么,怎么触发hasLayout 和 BFC ?
   一、那些元素自己就拥有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)
   二、哪些元素可以得到layout?
  • 在strict mode下,指定width或height的块级元素。
  • 兼容模式下, 指定了widht或height的任何元素
  • 设定了zoom属性的元素
  • 可编辑状态下的元素
  • 拥有viewlink行为的元素
  • 元素的Layout-flow属性跟父元素的不一样(rtl to ltr)
   三、怎么触发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 都有什么特性呢?
 
    一、hasLayout
  • 它会将元素限制在一个矩形的盒子内,从而保证元素的内容不会分散到另外一个盒子周围,例如,在IE引擎中,一个拥有布局边框的元素不会环绕相邻的浮动元素。这点很重要,在不少地方都用到,例如人人、微博、留言等左边的头像用浮动,右边的内容让其拥有布局。
  • 因为Layout使得浏览器渲染引擎要额外地在内存中调用算法来计算元素尺寸和方位,因此它并不轻量,它会消耗更多的内存,并可能致使性能的降低。
  • 会产生元素没法自适应大小的反作用,一个拥有Layout的元素不会“自动缩小”来适应其子元素,例如,一个绝对定位具备Layout的盒模型若是有一个拥有Layout的子元素,它是不会自动缩小来适应这个子元素的尺寸的。
  • 而一个拥有Layout的盒模型会被子元素给撑开(IE6下的heigh bug)
  • 人们一般利用Layout来解决IE6bug,特别是与相对定位元素有关的,但实际上,相对定位元素不须要拥有Layout,若是让它们拥有Layout在一些状况下反而会产生问题。
  • 若是一个元素拥有了布局,而且设置displayinline;那么它实际上跟设置了displayinlin-block;效果同样。app

    二、BFC布局

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

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

    (2)、BFC能够包含浮动的元素orm

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

    (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/

相关文章
相关标签/搜索