无。
WebKit 内核浏览器中,当使用脚本对拥有 'float' 特性以及 'overflow' 特性值不为 'visible' 特性的布局进行变更盒模型操作后,Chrome Safari 的 Reflow 计算会出现偏差,导致之后的 Repaint 操作时,无法渲染出布局内容。
由于页面局部没有被更新,可能会导致局部内容丢失,处于丢失内容中的功能将不可用。
Chrome Safari |
---|
从现有资料中得知,Reflow1 作为一个名词概念,最初出是在 Mozilla.org 中被提及,它表示了所有浏览器的布局引擎对元素实际位置的计算过程。在 Reflow 计算完成后,渲染引擎会根据布局数据绘制出页面内容,于是最终现实效果出现在浏览器窗口中,这个渲染过程被称作 Repaint1。如果页面中发生了影响整体布局的情况,将触发 Reflow 以及其后的 Repaint 动作,如:
详细说明可以参考 Mozilla.org 站点内文章:Notes on HTML Reflow。
注 1: 任何浏览器都存在 Reflow 及 Repaint 概念,有可能各个浏览器厂商有各自不同的命名方式,为避免混淆,本文中统一使用 Reflow、Repaint 单词来说明布局计算和布局渲染这两个概念。
我们看一个实例,例子中构造了出现这个问题必须的 5个条件:
代码如下:
<h2>产生问题的布局</h2> <input type="button" onclick="document.getElementById('A').style.height='29px'" value="祖先容器高度变小" /> <input type="button" onclick="document.getElementById('A').style.height='60px'" value="祖先容器高度恢复" /> <input type="button" onclick="document.getElementById('B').style.position='relative'" value="修复此问题" /> <div id="A" style="height:60px;background:gold;"> <div style="height:31px;background:red;"> <div style="overflow:auto;float:left; background:gray;width:500px; height:30px;" id="B" > 内容文字<br/> </div> <span>环绕文字</span> </div> </div>
高亮部分标注了产生问题的几个条件,此代码运行后,依次点击 "祖先容器高度变小"、"祖先容器高度恢复" 按键,使页面触发 Reflow 重绘布局,然后来看各浏览器中渲染情况。
IE6 IE7 IE8 Firefox Opera | Chrome Safari | |
---|---|---|
按键点击前 | ||
按键点击 "祖先容器高度变小" 和 "祖先容器高度恢复" 后 | ||
修复按键点击后 |
从表中对比可以看出,当最外层布局块高度变更到比最内层布局块小后,再还原为比最内层布局块高度大的时候:
以上代码中仅说明了最内层子元素在 'overflow:auto' 和 'float:left' 特性值设置时的表现情况,下面看在 'overflow:hiddden' 和 'float:right' 特性值设置时的表现。
我们将代码稍作调整:
<h2>最内容器 'float:right' 'overflow:auto'</h2> <input type="button"
onclick="document.getElementById('C').style.height='29px'" value="祖先容器高度变小" /> <input
type="button" onclick="document.getElementById('C').style.height='60px'" value="祖先容器高度恢复" />
<input type="button" onclick="document.getElementById('D').style.position='relative'" value="修复此问题"
/> <div id="C" style="height:60px;background:gold;"> <div
style="height:31px;background:red;"> <div style="overflow:auto;float:right; background:gray;height:30px;" id="D" > 内容文字<br/> </div>
<span>环绕文字</span> </div> </div>
<h2>最内容器 'float'
'overflow:hidden'</h2> <input type="button"
onclick="document.getElementById('E').style.height='29px'" value="祖先容器高度变小" /> <input
type="button" onclick="document.getElementById('E').style.height='60px'" value="祖先容器高度恢复" />
<input type="button" onclick="document.getElementById('F').style.position='relative'" value="修复此问题"
/> <div id="E" style="height:60px;background:gold;"> <div
style="height:31px;background:red;"> <div style="overflow:hidden;float:left; background:gray;height:30px;" id="F" >
内容文字<br/> </div> <span>环绕文字</span> </div> </div>
各览器中渲染情况:
'float:right' | IE6 IE7 IE8 Firefox Opera | Chrome Safari |
---|---|---|
按键点击前 | ||
按键点击 "祖先容器高度变小" 和 "祖先容器高度恢复" 后 | ||
修复按键点击后 |
'overflow:hidden' | IE6 IE7 IE8 Firefox Opera | Chrome Safari |
---|---|---|
按键点击前 | ||
按键点击 "祖先容器高度变小" 和 "祖先容器高度恢复" 后 | ||
修复按键点击后 |
在进一步修改验证之后,可发现 WebKit 渲染引擎的这个 Reflow/Repaint 问题与最内子元素同时设置 'float' 和 'overflow' 特性值不为 'visible' 有关。
根据这个特性可以继续验证出,如果去除 float' 和非 'overflow:visible' 特性值中任意一个,就会不出现此渲染问题。
或者在不修改特性值设定情况下,使最外层祖先容器高度设置变更大于等于最内容器计算高度,以及中层容器高度设置小于最内容器计算高度时,同样不会出现渲染问题。
具体验证代码不在文档内给出,读者可以运行下方的 测试用例 页面,自行验证。
由此可以得出结论:在本问题情况下,WebKit 渲染引擎浏览器执行 Reflow 计算后由于某种原因,执行 Repaint 重绘机制不完善,导致局部内容没有被重绘。
应尽量避免出现类似的布局结构,如果无法避免,并出现了上文所描述的布局异常,根据实际情况可以使用以下方案解决:
操作系统版本: | Windows 7 Ultimate build 7600 |
---|---|
浏览器版本: |
IE6
IE7 IE8 Firefox 3.6.10 Chrome 7.0.544.0 dev Safari 5.0.2 Opera 10.62 |
测试页面: | webkit_lost_layout.html |
本文更新时间: | 2010-10-12 |
webkit Chrome Safari float overflow hidden reflow layout repaint