转自: http://osmn00.com/blog/front-end/7.html
注:
[1] 高手可绕开。
[2] 无特殊说明,针对的都是自左向右读写的语言,如汉语、英语等。
[3] 感谢未来 和小志 的纠错指点,文章里相应部分已修改。
【一】先从一个简单的案例说起
先来看一段HTML代码:
这是一个无序列表UL,有6个子列表项LI。我们给他加上一些表现代码:
结果很显然,6个行高是26像素的LI元素将父容器UL在垂直方向撑开(可见的背景颜色区域可说明这点),父容器UL此时的高度等同于内部全部LI元素的行高之和。
但如果我们不想要一个垂直的列表,而是希望得到一个在水平方向上排列的呢?那我们可以对上面的CSS进行一个简单的修改,为所有的LI元素设置左浮动,或者设置所有LI元素的display属性为inline(但我们这里不详细讨论这个方法,因为它和我们下面要说的主角“overflow:hidden” 没什么关系):
OK,我们看到所有LI都按照我们所想的那样在水平方向自左向右的排列了。
像上面说的,使用display:inline也可以达到同样的效果。因为这个属性是将元素设置为内联元素,而我们知道,内联元素在文档流中是在一行中按照先后顺序自左向右排列的,所以这么设置也可以做到我们想要的效果。
回到正题,此时我们有了一个水平排列的列表,但我们却发现,父容器UL的背景色不见了。
【二】分析
那么,是什么导致了父容器的背景色无法显示出来呢?
先来回顾一点基础:
(1)当一个元素未设置明确的宽(width)时,那么,若它是一个块元素,其自身BOX宽度——或者形象的称呼为它的“占地宽度”(水平格式化七大属性 [margin-left、border-left、padding-left、width、padding-right、border-right、margin-right] 之和)会等于其父容器的内容区(width值)宽度;若它是一个内联元素,其自身BOX宽度则同父容器内容区宽度无关,而是等于其左右外边距+左右边框宽度+左右内边距+内容部分的文字宽度。
(2)当一个元素未设置明确的高(height)时,那么,若他是一个块元素,其自身内容区高度,取决于其内部子元素,而同父元素无关;若其是内联元素,其行内框高度等同于line-height值。
需要注意的是,以上2条都只针对元素按照正常的文档流排列。
回到我们上面那个消失了背景的UL案例。当我们还未给子元素LI设置任何浮动时,LI以符合正常文档流的形式存在于父容器UL中,他们会正常的将父容器UL的高度撑大。
当我们为他的子元素LI设置了浮动时,LI实际上便脱离了正常的文档流,虽然表面上被父级控制,实际上已经长翅膀飞了,浮动元素不占任何正常文档流空间,而浮动元素的定位还是基于正常的文档流(from 未来 )。
因为子元素脱离了正常的文档流,不占任何正常文档流空间。所以,当我们为父容器设置了一个背景时,这个背景不会显示——因为父容器里似乎什么都没有,那些子元素都浮起来脱离文档流了。但当我们再向父容器内部写入其他一些未脱离文档流的内容时,父容器的背景才会显现。见demo 3 。
【三】解决方案
OK。我们现在可以明确,这一切都是由于内部子元素的浮动造成的,按照CSS规范,浮动元素(floats)会被移出文档流,不会影响到块状盒子的布局而只会影响内联盒子(通常是文本)的排列。因此当其高度超出包含容器时,一般父容器不会自动伸长以闭合浮动元素。那么现在要做的,就是使得父容器可以自动闭合浮动元素。
有些人遇到这种问题,会为父元素设置一个明确的高度值,或者在UL标签闭合前,在里面加一个清除浮动(clear:both)的元素。这是个解决办法,但不是最佳办法。因为我们还需要考虑代码的书写效率、可重用性、可维护性及在此基础上的精简节约。想想打开一个页面的CSS文件,满眼都是写死的高度或者无语义的<br clear=”both;” />,那会是什么感觉?
使用“overflow:hidden”。
overflow:hidden 用于隐藏超出父容器内容区范围的内容。同时也可以起到清除浮动的作用,使得不处在正常文档流中的子元素回到文档流。
其他的方法可以参照文章结尾处的《清理浮动全家》 及《学习CSS:我们一起认识CSS闭合浮动元素》 (未找到原文出处)。