В некоторых ситуациях Firefox грубо просчитывает ширину некоторых элементов DOM, что, в свою очередь, приводит к разрыву макетов.
Этот пример jsFiddle дает пример проблемы. Цифры, отображаемые под таблицей, - это ширина (в пикселях) div
которая затенена темно-серой и ее родителя (как сообщается jQuery). Сравните результаты, полученные в последних версиях Firefox (или IE 11) и Chrome (или Safari). Chrome всегда сообщает 250 обоим ширинам (как и ожидалось), но Firefox всегда сообщает большее количество (хотя точное число может зависеть от ОС и/или версии FF и/или фазы луны). В результате этого недостаточно места для отображения элементов svg
в следующем td
в 3/ряд.
(Еще более сбивает с толку: цифры, отображаемые под таблицей, будут меняться в зависимости от количества элементов svg
включенных во второй элемент td
.)
Это неустойчивое/непредсказуемое поведение делает практически невозможным проектирование макета.
Как я могу гарантировать, что FF будет правильно вычислять такие ширины или, альтернативно, как я могу обойти эту ошибку?
EDIT: обновлен 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));
Если вы удалите правило inline-block
для .button-container > div
, он заставляет два divs сидеть на отдельных строках, позволяя таблице принимать согласованную ширину.
Что происходит, браузер пытается поместить элементы в одну строку. Ячейка в таблице без инструкций ширины или переполнения будет расширяться, чтобы разместить внутри нее строки содержимого. Поскольку два элемента являются встроенными, они считаются одной строкой. Текст обертывается, как и следовало ожидать (браузер выполняет хорошую работу, защищая целостность вашего содержимого), но это произвольно, поскольку вычисляется ширина; он влияет на вычисленную ширину линии, которую формируют элементы, и, следовательно, толчок к расширению ячейки таблицы. Браузер пытается взять то, что вы ему дали, и понять его, в то время как он также пытается сохранить целостность и разборчивость ваших данных, потому что это таблица и какие таблицы делают.
Это еще один хороший пример того, почему таблицы не являются подходящим инструментом для макета. Они предназначены для размещения и представления данных, поэтому они выполняют хорошую работу и определяют размер текста. Различные пользовательские агенты имеют разные стратегии, когда дело доходит до того, как это выполняется - все это входит в спецификацию. Когда вы злоупотребляете элементом, вам приходится сталкиваться с конструктивными свойствами, которые не подходят для вашего прецедента.
Скрипт: http://jsfiddle.net/Cy7dA/
Это вовсе не "просчет ширины".
Ваша проблема заключается в том, что ваш ярлык и ввод различаются по ширине в обоих браузерах. Дополнительная ширина затем нажимает кнопку-контейнер и td.
Постарайтесь, чтобы ваша комбинация ввода/метки была совместима между браузерами (вам, вероятно, нужны явные поля на входе), и ваша проблема решена.
.button-container
, но исходная ситуация была такова, что в Windows требовалась только одна строка, а в OS X - две строки , Расположение в одну строку, когда это было возможно, было предпочтительным, и это было причиной дляinline-block
. Без этого две линии будут применены, будь то ...