Reputation: 35331
Under some situations, Firefox grossly miscalculates the widths of some DOM elements, which in turn causes layouts to break.
This jsFiddle gives an example of the problem. The numbers displayed below the table are the widths (in pixels) of the div
that is shaded dark-gray, and of its parent (as reported by jQuery). Compare the results produced by the latest versions of Firefox (or IE 11) and Chrome (or Safari). Chrome always reports 250 for both widths (as expected), but Firefox always reports a larger number (though the exact number may depend on the OS and/or version of FF and/or phase of the moon). As a result, there's not enough room to render the svg
elements in the next td
at 3/row.
(More bewildering still: the numbers displayed below the table will vary according to the number of svg
elements included in the second td
element.)
This erratic/unpredictable behavior makes it practically impossible to design a layout.
How can I ensure that FF will compute such widths correctly, or alternatively, how can I work around this bug?
EDIT: updated jsFiddle (including the link to it).
Now, to keep the gods of SO happy:
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));
Upvotes: 0
Views: 344
Reputation: 50612
If you remove the inline-block
rule for .button-container > div
, it forces the two divs to sit on separate lines, allowing the table to take on a consistent width.
What is happening there is the browser is trying to put the elements on the same line. A cell in a table with no explicit width or overflow instructions will grow wider to accommodate the content lines inside it. Because the two elements are inline, they are considered a single line. The text wraps as you would expect (the browser does a good job protecting the integrity of your content), but this is arbitrary as far as the width calculation goes; it affects the calculated width of the line that the elements form, and therefore pushes the table cell open wider. The browser is trying to take what you gave it and make sense of it while it also tries to preserve the integrity and legibility of your data, because it is a table and that's what tables do.
This is another good example of why tables are not the right tool for layout. They are designed to accommodate and present data, so they do a good job flowing and sizing around text. Different user agents have different strategies when it comes to how this is accomplished -- that is all within the specification. When you abuse the element, you wind up having to contend with design properties that do not suit your use case.
Fiddle: http://jsfiddle.net/Cy7dA/
Upvotes: 1
Reputation: 39014
It isn't "miscalculating the width" at all.
Your problem is simply that your label and input are different widths in both browsers. The extra width is then pushing the button-container and td out further.
Try to get your input/label combo consistent between the browsers (you probably need explicit margins on the input) and your problem is solved.
Upvotes: 1