前言:发现这个问题的起因是在写一个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.创建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).
BFC中,盒子从包含块的顶部一个个在垂直方向上排列。
两个兄弟元素的垂直距离由
margin
决定。同一个BFC中的块级兄弟元素的垂直外边距会被叠加。在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>
效果图:
在这里我给.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
同时设置浮动时,效果如下:
当我给他们的父元素.wrapper
设置overflow:hidden
时,.wrapper
包含.last
和.first
效果如下:
这个解决方法应用原理如下:
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的高度会包含浮动元素高度。
3. 用overflow解决图片环绕
这是困扰我的第二大问题。
示例如下
从图一到图二的变化仅仅是给p
设置了overflow:hidden
属性。
这个应用到的原理我觉得应该是:
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里的每个盒子元素的左外边距都紧贴包含块的左边距。
同时在其他参考文章中看到BFC的还有一个属性是:
BFC的区域不会与float box重叠。
我想这一点能很清除的解释图二出现的原因。但我尚未在w3 spec里找到相应的描述。如果有小伙伴看到了,希望能告诉我一下~
总结
-
触发BFC的条件:
float
的属性不是none;overflow
的属性不是visible;position
的属性是absolute,fixed;display
的属性是:inline-block,table-cells,table-caption.
-
BFC的布局特性:
内部盒子在垂直方向一个接一个放置。
兄弟元素的外边距由
margin
决定,在同一个BFC里的垂直边距会叠加。(解决办法:创建一个新的BFC)BFC的高度包含浮动元素。(可用以消除浮动)
BFC的区域不会与浮动盒子重叠。(解决图片环绕效果)
BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。
参考资料
http://www.w3cplus.com/css/understanding-block-formatting-contexts-in-css.html
http://kayosite.com/block-formatting-contexts-in-detail.html
http://www.cnblogs.com/lhb25/p/inside-block-formatting-ontext.html
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。