shrink-to-fit 可以理解为 "收缩至合适" ,代表了浏览器对于计算后宽度为 'auto' 时的非替换浮动元素宽度计算所要遵循的标准。此外除了非替换浮动元素,对非替换绝对定位元素、非替换行内块元素的宽度为 auto 时也遵循此计算方式。
根据 W3C CSS2.1 规范中的描述,shrink-to-fit 的宽度计算方法与 'table-layout' 特性为 'auto'(即自动表格布局)时对于单元格的宽度计算方法类似。大致为:
综上所述:
shrink-to-fit 的宽度 = min ( max (首选最小宽度, 可用宽度) , 首选宽度)
关于 shrink-to-fit 的更多资料,请参考 CSS2.1 规范 10.3.5 Floating, non-replaced elements 中的内容。
对于宽度为 0% 的 IMG 元素的包含块的 shrink-to-fit 算法,Firefox Chrome Safari 与 IE6 IE7 IE8 Opera 存在差异。
当宽度为 0% 的 IMG 元素的包含块的宽度由 shrink-to-fit 算法决定的时候,各浏览器中的显示效果可能存在差异,严重的情况下会造成局部布局混乱。
所有浏览器 |
---|
该问题的根本原因在于包含 'width : 0%' 的 IMG 元素的包含块使用 shrink-to-fit 算法计算宽度的时候各浏览器取的首选宽度 (preferred width)不同。
分析以下代码:
<html> <head></head> <body> available width: 180px; width:0%; <div style="width:200px;background:red;padding:5px;"> <div id="stf1" style="float:left;border:5px solid;padding:5px;background:gold;"> <img src="google_small.gif" style="width:0%;" /> </div> </div> <br/><br/><br/> available width: 20px; width:0%; <div style="width:40px;background:red;padding:5px;"> <div id="stf2" style="float:left;border:5px solid;padding:5px;background:gold;"> <img src="google_small.gif" style="width:0%;" /> </div> </div> <br/><br/><br/> <div id="info"></div> <script type="text/javascript"> window.onload = function(){ var $ = function(id){return document.getElementById(id);}; function info(msg){ $("info").innerHTML += "computed width : " + msg + "px<br />"; } var cs1 = window.getComputedStyle ? window.getComputedStyle($("stf1"),null) : $("stf1").currentStyle, cs2 = window.getComputedStyle ? window.getComputedStyle($("stf2"),null) : $("stf2").currentStyle; info($("stf1").offsetWidth - parseInt(cs1.paddingLeft) - parseInt(cs1.paddingRight) - parseInt(cs1.borderLeftWidth) - parseInt(cs1.borderRightWidth)); info($("stf2").offsetWidth - parseInt(cs2.paddingLeft) - parseInt(cs2.paddingRight) - parseInt(cs2.borderLeftWidth) - parseInt(cs2.borderRightWidth)); } </script> </body> </html>
上述代码中需要使用 shrink-to-fit 计算宽度的元素是 DIV[id="stf1"] 和 DIV[id="stf2"] (以下简称 "stf1" 和 "stf2") 。 参考以上代码我们首先可以确定它们各自的可用宽度 (available width)为 180px 和 20px, 而图片 "google_small.gif" 内在宽度为 114px,分别小于和大于 "stf1" 和 "stf2" shrink-to-fit 算法的可用宽度。 通过对比两者的渲染结果和宽度的计算值,我们基本可以得出各浏览器对于 "stf1" 和 "stf2" 不同的 shrink-to-fit 算法。
各浏览器中表现如下:1
IE6 IE7 IE8 Opera | Firefox Chrome Safari |
---|---|
注1:这里忽略一些不相干的问题的影响,比如 IE6 IE7 IE8(Q) 中浮动元素会影响其 hasLayout 的包含块高度的计算。
根据测试结果,我们猜测在各浏览器中 'stf1' 和 'stf2' 的计算公式为:
shrink-to-fit Element | IE6 IE7 IE8 Opera | Firefox Chrome Safari |
---|---|---|
stf1 | 0px = min (max (0px, 180px), 0px) | 114px = min (max (0px, 180px), 114px) |
stf2 | 0px = min (max (0px, 20px), 0px) | 20px = min (max (0px, 20px), 114px) |
即 IE6 IE7 IE8 Opera 中宽度为 0% 的 IMG 元素的包含块宽度 'shrink-to-fit' 算法中首选宽度总为0, 而在 Firefox Chrome Safari 中首选宽度为图片内在宽度。
进一步可以推测出,当使用宽度为 0% 的 IMG 元素参与计算 'shrink-to-fit' 的首选宽度时,IE6 IE7 IE8 Opera 会先将 IMG 元素的宽度计算为 0, 再计算其包含块的宽度;而其它浏览器则先使用 IMG 元素的内在宽度计算包含块的宽度,再计算 0% 的 IMG 元素的宽度。
尽量避免设置 IMG 元素的宽度为 0%,可以用 0px 替代。
操作系统版本: | Windows 7 Ultimate build 7600 |
---|---|
浏览器版本: |
IE6
IE7 IE8 Firefox 3.6.10 Chrome 7.0.524.0 dev Safari 5.0.2 Opera 10.62 |
测试页面: | IMG_width_0percent.html |
本文更新时间: | 2010-09-19 |
shrink-to-fit IMG width percent