根据 W3C CSS2.1 关于浮动的叙述中对 float 与 block formatting context12 之间的关系的描述:
表格的 border-box、块级的替换元素、或是在普通流中创建了新的 block formatting context(如元素的 'overflow' 特性不为 'visible' 时)的元素不可以与位于相同的
block formatting context
中的浮动元素相重叠。如果有必要,布局实现中应清除上述元素而将其放置在之前的所有浮动元素之下的一行,但也可能在有足够剩余空间的情况下与浮动元素相邻。它们甚至可能会使上述元素的 border-box
比根据普通流中的非替换块级元素宽度算法计算而来的更窄。CSS2 并没有定义用户端何时将上述元素紧邻浮动元素放置或是变窄。
此外,CSS 规范在其他章节中说明了何种情况下会创建新的 block formatting context :
CSS 规范中仅提到了 block formatting context 与浮动元素之间 "不可重叠" ,并没有详细描述如何处理它们之间的布局关系。
关于 block formatting context 及其相关的详细信息,请参考 CSS2.1 规范 9.4.1 Block formatting contexts、17.4 Tables in the visual formatting model、9.5 Floats 中的内容。
注1. 由于 IE6 IE7 IE8(Q) 中没有 block formatting context 的概念,取而代之的是 hasLayout 特性。关于 hasLayout 与 block
formatting context 之间的关系参见: "不能在 IE6 IE7 IE8(Q) 中触发 hasLayout 并在其他浏览器中创建 block formatting context
的元素的表现在某些情况下会有差异" 。
注2. 为方便描述,以下段落将 block formatting context 以 BFC 代替。
若容器的宽度、浮动元素的宽度、BFC 的宽度的值设置不当,导致 BFC 的宽度大于 "容器的剩余空间宽度" 时,在各浏览器之间可能会触发兼容性问题,最终造成布局上的极大的差异,如内容丢失、错位等。
所有浏览器 |
---|
由于可以创建 BFC 的条件很多,这里以最常见的利用 'overflow:hidden' 创建 BFC 为例,在 IE6 IE7 IE8(Q) 中则靠为元素设置宽度触发其 hasLayout 特性。
分析以下代码:bfc_lesser.html
<style> * { font:12px Arial; } .container { background:silver; width:150px; height:30px; } .float { background:darkgray; float:left; width:80px; } .bfc { background:dimgray; overflow:hidden; color:white; } </style> <div class="container"> <div class="float">FLOAT(80)</div> <div class="bfc" style="width:60px;">BFC(60)</div> </div>
测试代码中容器 【container】 的宽度为 150px,内部包含一个左浮动宽度为 80px 的元素 【float】,及一个设置了 overflow:hidden 的宽度60px的元素 【bfc】 ,则 【bfc】 由于 'overflow' 特性不为 visible 而创建了新的 BFC。
各浏览器中效果如下:
所有浏览器 |
---|
1 |
可见,当容器的剩余宽度足够容纳 BFC 的宽度时,各浏览器的处理相同,BFC 被放置到了浮动元素所在行的剩余空间内。
注1. IE6 IE7(Q) IE8(Q) 出现的 "3px Bug" 不是本文讨论的重点,由于这个 Bug 触发的差异在本文中将被忽略。
分析以下代码:bfc_median.html
<style> * { font:12px Arial; } .container { background:silver; width:150px; height:30px; } .float { background:darkgray; float:left; width:80px; } .bfc { background:dimgray; overflow:hidden; color:white; } </style> <div class="container"> <div class="float">FLOAT(80)</div> <div class="bfc" style="width:90px;">BFC(90)</div> </div>
测试代码中容器 【container】 的宽度为 150px,内部包含一个左浮动宽度为 80px 的元素 【float】,及一个设置了 overflow:hidden 的宽度 90px 的元素 【bfc】,则 【bfc】 由于 'overflow' 特性不为 visible 而创建了新的 BFC。
各浏览器中效果如下:
IE6 IE7 IE8 Chrome Safari Opera | Firefox |
---|---|
可见,当容器的剩余宽度不够容纳 BFC 的宽度,但 BFC 的宽度小于容器的宽度时,各浏览器的处理产生差异:
下面继续测试在 Firefox 中的一种影响布局的现象:bfc_median_firefox.html
<style> * { font:12px Arial; } .container { background:silver; width:150px; height:30px; } .float { background:darkgray; float:left; width:80px; } .bfc { background:dimgray; overflow:hidden; color:white; } </style> <div class="container"> <div class="float">FLOAT(80)</div> <div class="bfc" style="width:90px;">BFC(90)</div> </div> <br /> <div class="container" style="padding-top:5px;"> <div class="float">FLOAT(80)</div> <div class="bfc" style="width:90px;">BFC(90)</div> </div> <br /> <div class="container" style="border-top:5px solid black;"> <div class="float">FLOAT(80)</div> <div class="bfc" style="width:90px;">BFC(90)</div> </div> <br /> <div class="container" style="display:inline-block;"> <div class="float">FLOAT(80)</div> <div class="bfc" style="width:90px;">BFC(90)</div> </div>
测试代码分为 4 组,第一组与上一段中的代码相同,第二组为【container】添加了 padding-top:5px,第三组为【container】添加了 border-top:5px solid black,第四组为【container】添加了 'display:inline-block'。
各浏览器中效果如下:
IE6 IE7 IE8 Chrome Safari Opera | Firefox |
---|---|
可见,容器的 'padding-top' 不为 0、'border-top-width' 不为 0、以及容器本身也创建了 BFC 后,Firefox 中对于【BFC】宽度介于 "容器剩余宽度" 与 "容器宽度" 之间的情况下,【BFC】会显示到浮动元素的下一行。
分析以下代码:bfc_greater.html
<style> * { font:12px Arial; } .container { background:silver; width:150px; height:30px; } .float { background:darkgray; float:left; width:80px; } .bfc { background:dimgray; overflow:hidden; color:white; } </style> <div class="container"> <div class="float">FLOAT(80)</div> <div class="bfc" style="width:151px;">BFC(151)</div> </div> <br /> <div class="container" style="padding-top:5px;"> <div class="float">FLOAT(80)</div> <div class="bfc" style="width:151px;">BFC(151)</div> </div> <br /> <div class="container" style="border-top:5px solid black;"> <div class="float">FLOAT(80)</div> <div class="bfc" style="width:151px;">BFC(151)</div> </div> <br /> <div class="container" style="display:inline-block;"> <div class="float">FLOAT(80)</div> <div class="bfc" style="width:151px;">BFC(151)</div> </div>
测试代码分为 4 组,与上一段中的区别为【BFC】的宽度变为了 151px。
各浏览器中效果如下:
IE6 IE7 IE8 Opera | Firefox | Chrome Safari |
---|---|---|
1 |
注1. IE6 IE7(Q) IE8(Q) 出现的 "width/height的设定值可能被其内容撑大" 不是本文讨论的重点,由于这个 Bug 触发的差异在本文中将被忽略。
合理地设置容器的宽度、浮动元素的宽度、BFC 的宽度的值,尽量保证 BFC 的宽度小于 "容器的剩余空间宽度" 。若需要 BFC 折行显示在新的一行上,可以通过 BFC 设置 'clear' 特性等手段使其换行。
操作系统版本: | Windows 7 Ultimate build 7600 |
---|---|
浏览器版本: |
IE6
IE7 IE8 Firefox 3.6.6 Chrome 6.0.466.0 dev Safari 5.0 Opera 10.60 |
测试页面: |
bfc_lesser.html
bfc_median.html bfc_median_firefox.html bfc_greater.html |
本文更新时间: | 2010-07-21 |
Block formatting context float 浮动