转载

BFC(Block Formating Context)和overflow解决部分问题的原理

前言:发现这个问题的起因是在写一个css animation demo的时候为了不让图片溢出包含块,而给包含块设置了 {overflow:hidden;} 属性导致动画效果不能实现。于是查找 overflow 的相关属性时又遇到了其他问题。现在终于有些解决。

关于BFC

Boxes in the normal flow belong to a formatting context, which may be block or inline, but not both simultaneously. Block-level boxes participate in a block formatting context. Inline-level boxes participate in an inline formatting context.

普通文档流里的盒子属于一种格式化上下文,它可能是块状或者行内元素,但是不可能同时是二者。块状盒子属于块状格式化上下文(BFC),行内盒子属于行内格式化上下文。

w3 spec里是这样定义BFC的:

Floats, absolutely positioned elements, block containers (such as inline-blocks, table-cells, and table-captions) that are not block boxes, and block boxes with 'overflow' other than 'visible' (except when that value has been propagated to the viewport) establish new block formatting contexts for their contents.

翻译过来就是:

  1. 1.创建BFC的条件:

    • float 的属性不是none;

    • overflow 的属性不是visible;

    • position 的属性是absolute,fixed;

    • display 的属性是:inline-block,table-cells,table-caption.

只要满足以上条件我们就触发了BFC.

那么BFC有哪些属性呢?

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.

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).

  1. BFC中,盒子从包含块的顶部一个个在垂直方向上排列。

  2. 两个兄弟元素的垂直距离由 margin 决定。同一个BFC中的块级兄弟元素的垂直外边距会被叠加。

  3. 在BFC中,每个盒子的左外边距接触包含块的左边(从右到左的也一样),即使存在浮动元素也一样(即使盒子的行内盒子会由于浮动和紧缩,即这个盒子会由于浮动而变窄)。

用BFC属性解决 overflow 相关问题

接下来,我们用上面的知识来解决我的疑问:

1. 用overflow解决外边距叠加

示例如下

   <div class="wrapper">  <div class="first"></div>   <div class="last"></div> </div> <div class="container">  <div class="first"></div>  <div class="last bfc"></div> </div> 
  <style>  .wrapper,.container{border:2px solid #cff;width: 500px;}  .wrapper{float: left;}  .first,.last{width: 300px;height: 50px;margin: 20px;}  .first{background-color: pink;}  .last{background-color: yellow;}  .bfc{overflow: hidden;} </style> 

效果图:

BFC(Block Formating Context)和overflow解决部分问题的原理

在这里我给 .wrapper 设置了 float:left ,这样 .container 就会在 .wrapper 下方,同时我给 .container 里的 div.bfc 即黄色的div设置了 overflow:hidden ,这样就触发了 div.bfc 的BFC属性。我们可以看到,黄色的div出现在 .wrapper 的黄色的div的下方。很容易可以看出, .container 里的两个div的外边距并未叠加(否则就看不到 .container 里的黄色块。)

这个用到了上面说的BFC的特性之二:

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. 用overflow清除浮动

还是上面的代码,当我给 .last .first 同时设置浮动时,效果如下:

BFC(Block Formating Context)和overflow解决部分问题的原理

当我给他们的父元素 .wrapper 设置 overflow:hidden 时, .wrapper 包含 .last.first 效果如下:

BFC(Block Formating Context)和overflow解决部分问题的原理

这个解决方法应用原理如下:

In addition, if the element has any floating descendants whose bottom margin edge is below the element's bottom content edge, then the height is increased to include those edges. Only floats that participate in this block formatting context are taken into account, e.g., floats inside absolutely positioned descendants or other floats are not.

即BFC的高度会包含浮动元素高度。

2. 用overflow解决图片环绕

这是困扰我的第二大问题。

示例如下

正文到此结束
Loading...