如何解决Firefox错误计算的宽度问题

时间:2013-12-03 03:56:17

标签: html css firefox svg

在某些情况下,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));

2 个答案:

答案 0 :(得分:1)

根本不是“误算宽度”。

您的问题很简单,两个浏览器中的标签和输入都是不同的宽度。然后额外的宽度是按下按钮容器并进一步推出。

尝试让浏览器之间的输入/标签组合保持一致(您可能需要在输入上显示边距)并解决您的问题。

答案 1 :(得分:1)

如果删除inline-block的{​​{1}}规则,则会强制两个div位于不同的行上,从而使表格具有一致的宽度。

正在发生的事情是浏览器试图将元素放在同一行上。表中没有明确宽度或溢出指令的单元格将变宽,以容纳其中的内容行。因为这两个元素是内联的,所以它们被认为是单行。文本包装正如您所期望的那样(浏览器可以很好地保护内容的完整性),但就宽度计算而言,这是任意的;它影响元素形成的线的计算宽度,因此推动表格单元格更宽。浏览器试图接受你提供的内容并理解它,同时它也试图保持数据的完整性和易读性,因为它是一个表,这就是表的作用。

这是表格不适合布局的另一个很好的例子。它们旨在容纳和呈现数据,因此它们可以很好地处理文本的流程和大小。当涉及如何实现时,不同的用户代理具有不同的策略 - 这都在规范内。当您滥用该元素时,您最终不得不与不适合您的用例的设计属性竞争。

小提琴:http://jsfiddle.net/Cy7dA/