在某些情况下,Firefox会严重错误计算某些DOM元素的宽度,从而导致布局中断。
这个jsFiddle给出了一个问题的例子。表格下方显示的数字是深灰色阴影的div
及其父级(由jQuery报告)的宽度(以像素为单位)。比较最新版本的Firefox(或IE 11)和Chrome(或Safari)产生的结果。 Chrome总是为两个宽度报告250(如预期的那样),但Firefox总是报告更大的数字(尽管确切的数字可能取决于操作系统和/或FF的版本和/或月亮的相位)。因此,没有足够的空间在下一个svg
3 /行中呈现td
个元素。
(更令人困惑的是:表格下方显示的数字会根据第二个svg
元素中包含的td
元素的数量而有所不同。)
这种不稳定/不可预测的行为使得设计布局几乎不可能。
如何确保FF能够正确计算这样的宽度,或者我如何解决这个错误呢?
编辑:更新了jsFiddle(包括指向它的链接)。
现在,为了让SO的众神高兴:
body > div,table,table *{outline:1px solid red;}
html,body{height:100%;}
*{
-webkit-box-sizing:border-box;
-moz-box-sizing:border-box;
box-sizing:border-box;
}
*{margin:0;padding:0;border:0;}
table{
border-spacing:0;
border-collapse:collapse;
}
body{
font-family:courier;
font-size:13px;
background-color:palegoldenrod;
}
body > div{
width:312px;
margin:0 auto;
padding:40px 0 0;
background-color:white;
min-height:100%;
}
label{
display:block;
padding:0 1ex;
}
.button-container{
color:white;
background-color:#555;
}
.button-container > div{
display:inline-block;
}
.button-container > div:first-child{
font-weight:bold;
}
.ul-container > div{
width:100%;
border:1px solid black;
-webkit-border-radius:4px;
border-radius:4px;
}
ul{list-style:none;}
li{
width: 72px;
float:left;
margin: 0px 5px 1px;
padding: 0px 5px;
border-width: 1px;
line-height: 14px;
}
br{
clear:left;
}
body > div > div:last-child{margin:40px;}
<body>
<div>
<table><tbody><tr>
<td>
<div class="button-container">
<div>xxxx xxxxx</div>
<div>
<label> <input type="radio"> xxxx xxxx xxx xxxx xxxx </label>
</div>
</div>
<div class="ul-container" style="width: 250px;">
<div style="width: 248px;">
<ul style="width: 246px;">
<li>A</li><li>B</li><li>C</li><li>D</li><li>E</li><li>F</li><li>G</li><li>H</li><li>I</li>
</ul>
<br>
</div>
</div>
</td>
<td>
<div>
<svg width="20" height="20"></svg><svg width="20" height="20"></svg><svg width="20" height="20"></svg><svg width="20" height="20"></svg><svg width="20" height="20"></svg><svg width="20" height="20"></svg><svg width="20" height="20"></svg>
</div>
</td>
</tr></tbody></table>
<div></div>
</div>
(function ($) {
var $msg = $('body > div > div:last-child');
function showw (sel) {
var w = $(sel).width();
$('<span>', {text: '' + w})
.css('margin-left', 5)
.appendTo($msg);
console.log(w);
}
showw('.button-container');
showw('table td:first-child');
}(jQuery));
答案 0 :(得分:1)
根本不是“误算宽度”。
您的问题很简单,两个浏览器中的标签和输入都是不同的宽度。然后额外的宽度是按下按钮容器并进一步推出。
尝试让浏览器之间的输入/标签组合保持一致(您可能需要在输入上显示边距)并解决您的问题。
答案 1 :(得分:1)
如果删除inline-block
的{{1}}规则,则会强制两个div位于不同的行上,从而使表格具有一致的宽度。
正在发生的事情是浏览器试图将元素放在同一行上。表中没有明确宽度或溢出指令的单元格将变宽,以容纳其中的内容行。因为这两个元素是内联的,所以它们被认为是单行。文本包装正如您所期望的那样(浏览器可以很好地保护内容的完整性),但就宽度计算而言,这是任意的;它影响元素形成的线的计算宽度,因此推动表格单元格更宽。浏览器试图接受你提供的内容并理解它,同时它也试图保持数据的完整性和易读性,因为它是一个表,这就是表的作用。
这是表格不适合布局的另一个很好的例子。它们旨在容纳和呈现数据,因此它们可以很好地处理文本的流程和大小。当涉及如何实现时,不同的用户代理具有不同的策略 - 这都在规范内。当您滥用该元素时,您最终不得不与不适合您的用例的设计属性竞争。