BFC与haslayout

  前几天学习的时候看到了BFC这个词,好奇之余在网上查了相关文章,终于搞明白了BCF到底是什么东西。发现自己布局时早已使用过其特性解决问题,只是不知道这个具体概念以及内在原理。下面就谈谈我对BFC的理解吧。

  BFC是(Block Formatting Context)的缩写,中文翻译过来是块格式化上下文,是W3C CSS 2.1 规范中的一个概念,在CSS3中,BFC  叫做  Flow Root。其实从其字面意思上我们已经可以看出些端倪:context——上下文;其实我自己理解的就是提供参照,那么为什么东西提供参照呢?当然是包含在创建了BFC元素内部的子元素了。也就是说,BFC为其包含的子元素创建了一个布局环境,不同BFC之间互不影响,比如浮动元素会形成 BFC,浮动元素内部子元素的主要受该浮动元素影响,两个浮动元素之间是互不影响的。下面是W3C规范的创建了BFC的元素对其子元素的行为规则:

  1.In a block formatting context, boxes are laid out one after the other, vertically, beginning at the top of a containing block. The vertical distance between two sibling boxes is determined by the ‘margin‘ properties. Vertical margins between adjacent block-level boxes in a block formatting context collapse.

  【元素的子元素会一个接一个地放置。垂直方向上他们的起点是一个包含块的顶部,两个相邻的元素之间的垂直距离取决于‘margin‘ 特性。在BFC中相邻的块级元素的垂直边距会折叠。】 

  2.In a block formatting context, each box‘s left outer edge touches the left edge of the containing block (for right-to-left formatting, right edges touch). This is true even in the presence of floats (although a box‘s line boxes may shrink due to the floats), unless the box establishes a new block formatting context (in which case the box itself may become narrower due to the floats).

  【元素的子元素中,每一个子元素左外边与包含块的左边相接触(对于从右到左的格式化,右外边接触右边),即使存在浮动也是如此(尽管一个子元素的内容区域会由于浮动而压缩),除非这个子元素也创建了一个新的BFC,如它自身也是一个浮动。】

  英文部分是W3C原文,下面是中文翻译。翻译难免有偏差,把原文粘过来方便理解。下面简单解释下这两段话:

  1.第一段话前面没什么好说的,就是说BFC元素内部元素正常情况下会按照常规的文档流的形式布局,有意思的是第二句话“在BFC中相邻的块级元素的垂直边距会折叠”。好了,我们来看看这个垂直边距重叠的具体效果,代码如下:

<!DOCTYPE html>

<html>
<head>
    <title></title>
    <style type="text/css">
      .father{
        width: 700px;
        height: 500px;
        font-size: 100px;
        font-weight: bold;
        background-color: black;
         }
      .child1{
        width: 300px;
        height: 300px;
        background-color: red;
        margin-top: 50px;
        margin-bottom: 50px;
          }
      .child2{
        width: 500px;
        height: 300px;
        background-color: green;
        border: 5px solid black;
        margin-top: 50px;
        margin-bottom: 50px;
          }
      </style>
</head>
<body>
  <div class="father">
    <div class="child1">1</div>
    <div class="child2">2</div>
  </div>
</body>
</html>

我们会看到下图的效果:

            

可以看到,这里child1和child2同时设置了50px的margin-top和margin-bottom,但实际上child1和child2之间垂直距离总共只有50px,也就是说发生了垂直边距的重叠。而更过分的是,我们原本想让child1的顶部与father元素(背景为black)有50px的边距,但实际效果却是child1的margin将父元素顶部的外边距撑开了50px,而这个也是同一个BFC外边距会重叠的原因——因为原文是相邻元素,这个相邻包括相邻子元素与嵌套元素。换句话说,属于一个BFC时,两个元素才有可能发生垂直Margin的重叠,这个包括相邻元素,嵌套元素,只要他们之间没有阻挡(例如边框,非空内容,padding等)就会发生margin重叠。因此要解决margin重叠问题,只要让它们不在同一个BFC就行了,但是对于两个相邻元素来说,意义不大,没有必要给它们加个外壳,但是对于嵌套元素来说就很有必要了,只要把父元素设为BFC就可以了。这样子元素的margin就不会和父元素的margin发生重叠了。具体到上面的例子,如果我们给father元素设置border,padding,或者是除了值"visible"以外的overflow,都可以防止容器内的第一个子元素margin-top将容器上边距撑开的问题(border,padding使其不相邻,而overflow则是创建了新的BFC)。

  2.第二段话其实也没什么好解释的,意思就是说如果一个元素符合了成为 BFC 的条件,该元素内部元素的布局和定位就和外部元素互不影响(除非内部的盒子建立了新的  BFC), 是一个隔离了的独立容器。每个容器内的子元素的左边外边都与其自身的包含块的左边接触。

好了,简单解释了一下标准,下面就看看如何形成BFC,以及BFC的用途。

  满足下列条件之一均能形成一个BFC环境:    

      1)  float 的值不为 none;

      2)  overflow 的值不为 visible;

      3)  display 的值为  table-cell、table-caption 和 inline-block 之一;

      4)  position 的值不为  static 或  relative 中的任何一个;

 BFC一般有以下几个作用:

   1)包含浮动元素:

      我们知道,如果子元素浮动,父元素的高度会塌陷,但是如果让父元素形成BFC就能使其根据子元素的高度自适应。还是上面的代码,将father的宽高去掉,加上border:1px solid blue;并且给child1和child2都设置float:left。我们将会看到:

      

     (father元素的高度坍塌,上下border重叠)

     现在给father加上overflow:hidden:

      

      (father元素设置了overflow,创建了BFC,高度得以重新计算)

    2)利用BFC防止嵌套元素垂直边距重叠。这个就是前面的展示的例子。

    3)利用BFC防止被float元素覆盖:

      float元素会无视兄弟元素的存在,覆盖在兄弟元素的上面,我们可以给兄弟元素创建新的BFC来防止被覆盖:

      给child1设置float:left:

        

      (child2未创建BFC,被浮动元素child1覆盖)

      同时给child2设置overflow:hidden;

        

        (child2创建了BCF)

至此,对BFC已经有比较清晰的认识了,不过不是所有浏览器都支持BFC规则的,比如奇葩浏览器IE6、IE7。在IE6、7中像上文中这样利用BCF特性解决问题有时候不会得到预期的效果。不过好在在IE中有类似的haslayout属性:当元素的hasLayout属性值为false的时候,元素的尺寸和位置由最近拥有布局的祖先元素控制。当元素的hasLayout属性值为true的时候会达到和BFC类似的效果,元素负责本身及其子元素的尺寸设置和定位。IE这个属性的初衷是为了保持浏览器的性能,因为在理想情况下,所有元素都控制自己的尺寸和定位。但是,这在IE中会导致很大的性能问题。因此,IE开发团队决定只将布局应用于实际需要它的那些元素,这样就可以充分地减少性能开销。默认情况下,IE中下列标签的haslayout是true:

  

<html>, <body>

<table>, <tr>, <th>, <td>

<img>

<hr>

<input>, <button>, <select>, <textarea>, <fieldset>, <legend>

<iframe>, <embed>, <object>, <applet>

<marquee>

也即是说,默认情况下,这些标签可以控制决定其自身内部子元素的布局。

    此外,在IE6、7中,做如下设置将使元素的haslayout属性为true:

        1)position: absolute

        2)float: left|right

       3)display: inline-block

       4)width: 除 “auto” 外的任意值

       5)height: 除 “auto” 外的任意值

       6)zoom: 除 “normal” 外的任意值

       7)writing-mode: tb-rl

 在IE7中使用overflow: hidden|scroll|auto 也可以使hasLayout为true。

PS:具有“layout” 的元素如果同时 display: inline ,那么它的行为就和标准中所说的 inline-block很类似了:在段落中和普通文字一样在水平方向和连续排列,受 vertical-align影响,并且大小可以根据内容自适应调整。

总结:其实本文中提到的BCF的很多使用场合在此前的布局中都经常使用,只是以前一直仅仅将其当做一个技巧使用,现在总算明白其原理所在。知其然必知其所以然,才能走的更远。

                           

时间: 2024-08-01 20:05:00

BFC与haslayout的相关文章

BFC和haslayout

haslayout 的概念 haslayout 是Windows Internet Explorer渲染引擎的一个内部组成部分.在InternetExplorer中,一个元素要么自己对自身的内容进行计算大小和组织,要么依赖于父元素来计算尺寸和组织内容.为了调节这两个不同的概念,渲染引擎采用了 hasLayout 的属性,属性值可以为true或false.当一个元素的 hasLayout属性值为true时,我们说这个元素有一个布局(layout). 要想更好的理解 css, 尤其是 IE 下对 c

谈BFC和haslayout

今天提到BFC和haslayout,就顺带在网上查查资料,总结一下它们. CSS2我们再熟悉不过,当然它里面我们需要掌握的,就是CSS2的选择器和布局,选择器总共31种.避开这个不说,我们说布局. 布局经常用到的有浮动.定位,当然也需要知道盒子模型,这里的盒子模型不是说就是内边距.外边距.边框等,他们只是其中的一种. 盒子模型总共有5个:1) BFC:2) haslayout:3) 元素盒 :4) EM盒 :5) 行盒 BFC: 含义:顾名思义就是Block Formatting Context

关于BFC与haslayout

BFC与hasLayout都是CSS布局上的概念. 几个月前在微博上才了解什么是BFC,算是对布局有点初步的了解. hasLayout则是IE6.7产生许多bug的根源. 浮动.绝对定位元素,不是块框的块容器(inline-block, table-cell, and table-caption),以及设置了overflow属性(除了visible)的块框,它们会为它们的内容形成新的 block formatting contexts (BFC). 在一个BFC中,框一个接一个的排列.垂直方向上

BFC and Haslayout

一.BFC(Block Formatting Context) 相关网址:http://www.cnblogs.com/dolphinX/p/3508869.html 1. 怎样才能形成BFC float的值不为none. overflow的值不为visible. display的值为table-cell, table-caption, inline-block中的任何一个. position的值不为relative和static. 2.BFC的作用 不和浮动元素重叠 如果一个浮动元素后面跟着一

文本溢出、垂直外边距合并、BFC、hasLayout

今天学习文本溢出,又遇到了一些小问题,先上图: 关于文本溢出推荐:http://www.cnblogs.com/yzg1/p/5089534.html 从里面学习到单行文本和多行文本溢出, overflow:hidden;text-overflow: ellipsis是基本.然后在控制多行文本溢出的时候需要用到弹性伸缩盒子-webkit-box ,包括设置盒子的伸缩方向和显示的行数. 用div内嵌div做一个小测试:发现对子元素,margin-left有效但是margin-top是无效的,问题的

BFC与HasLayout的理解

1.(Block Formatting Contexts)BFC 定义 BFC(Block formatting context)直译为"块级格式化上下文".它是一个独立的渲染区域,只有Block-level box参与, 它规定了内部的Block-level Box如何布局,并且与这个区域外部毫不相干. 2.BFC布局规则: 内部的Box会在垂直方向,一个接一个地放置. Box垂直方向的距离由margin决定.属于同一个BFC的两个相邻Box的margin会发生重叠 每个元素的mar

什么是BFC,haslayout

BFC(Block Formatting Context)意思为“块级格式化范围” 是 W3C CSS 2.1 规范中的一个概念,它决定了元素如何对其内容进行定位,以及与其他元素的关系和相互作用.当涉及到可视化布局的时候,Block Formatting Context提供了一个环境,HTML元素在这个环境中按照一定规则进行布局.一个环境中的元素不会影响到其它环境中的布局.比如浮动元素会形成BFC,浮动元素内部子元素的主要受该浮动元素影响,两个浮动元素之间是互不影响的.这里有点类似一个BFC就是

BFC、haslayout

BFC(block块,f格式化,c上下文content )译为"块级格式化上下文" 它是指一个独立的块级渲染区域,只有Block-level BOX参与,该区域拥有一套渲染规则来约束块级盒子的布局,且与区域外部无关. CSS2.1中规定满足下列CSS声明之一的元素便会生成BFC. 根元素 float的值不为none overflow的值不为visible display的值为inline-block.table-cell.table-caption position的值为absolut

浅谈BFC和haslayout

一.BFC是什么? BFC(Block Formatting Context)直译为“块级格式化范围”. 其一般表现规则,我整理了以下这几个情况: 1.在创建了 Block Formatting Context 的元素中,其子元素按文档流一个接一个地放置.垂直方向上他们的起点是一个包含块的顶部,两个相邻的元素之间的垂直距离取决于 ‘margin’ 特性. 根据 CSS 2.1 8.3.1 Collapsing margins 第一条,两个相邻的普通流中的块框在垂直位置的空白边会发生折叠现象.也就