桌面上的Flexbox在Firefox中不起作用

时间:2016-01-04 21:09:18

标签: html css css3 flexbox

使用flexbox控制表格的布局在webkit浏览器中有效,但在Firefox中,<td>只能呈现与其内容一样宽的内容。

演示: http://codepen.io/afraser/pen/wMgbzr?editors=010

* {
  box-sizing: border-box;
}
table {
  border: 1px solid #ddd;
  width: 100%;
}
tbody {
  background: #fff;
}
tr {
  display: flex;
}
td:first-child {
  flex: 1 1 80%;
  background: mistyrose;
}
td:nth-child(2) {
  flex: 0 0 10%;
  background: Aquamarine;
}
td:nth-child(3) {
  flex: 0 0 10%;
  background: pink;
}
<table>
  <tbody>
    <tr>
      <td>Ted</td>
      <td>1</td>
      <td>100%</td>
    </tr>
    <tr>
      <td>Turd Ferguson</td>
      <td>2</td>
      <td>65%</td>
    </tr>
    <tr>
      <td>Hingle McKringleberry</td>
      <td>3</td>
      <td>99%</td>
    </tr>
  </tbody>
</table>

我尝试了几种变体,包括:

  • 分别使用flex-growflex-shrinkflex-basis
  • 使用flex-basis的像素代替百分数。
  • 使用table-layout: fixed

我在这里看不到任何记录:https://github.com/philipwalton/flexbugs并在其他地方干涸。有谁知道发生了什么事?

2 个答案:

答案 0 :(得分:9)

那是因为,根据CSS表格,当表格元素不是表格的子元素时,应该生成anonymous table objects

enter image description here

根据Flexbox Last Call Working Draft,匿名表是什么成为flex项,而不是表格单元格:

  

display的某些值会触发匿名框的创建   在原来的盒子周围。这是最外面的盒子 - 直接的孩子   flex container box - 成为flex item。对于   例如,给定两个带有display: table-cell的连续子元素,anonymous table wrapper box generated around them [CSS21]成为flex item

由于表格单元格不是弹性项目,因此忽略了flex属性。它适用于匿名表,但CSS选择器不能选择匿名元素。

然而,Chrome不同意该规范并决定封锁表格单元格。

然后CSS工作组decided标准化Chrome的行为:

  

如果你有一个弹性容器,并在其中放入两个表格单元格   不会独立成为弹性项目。他们将匿名包裹   表格,这将是flex。

     

但是,Chrome已经实施了它,因此每个项目都是独立的   一个弹性项目。 [...]因此它将表格单元格变成了块。

     

我在他们参加的会议上至少看过一次演讲   这样做的好处是可以为flex创建回退行为。 [...] 如果你是   不试图触发回退,我不知道你为什么要放一堆   flex中的表格单元格,并将其包含在匿名内容中。 [...]

     

已解决:只是阻止弹性和网格容器的子代。   不要做匿名的盒子修复

first Flexbox Candidate Recommendation以新决议发布:

  

display的某些值通常会触发创建   原盒子周围的匿名盒子。如果这样的框是flex item,则它首先被阻塞,因此创建匿名框   不会发生。例如,两个连续的flex items   display: table-cell将成为两个独立的display: block flex items,而不是被包装成一个   匿名表。

然后Firefox从版本47(bug 1185140)开始实施新行为。

对于旧版本,您可以手动将单元格设置为块:

.flex-container > td {
  display: block;
}

* {
  box-sizing: border-box;
}
table{
  border: 1px solid #ddd;
  width: 100%;
}
tbody {
  background: #fff;
}
tr {
  display: flex;
}
td {
  display: block;
}
td:first-child {
  flex: 1 1 80%;
  background: mistyrose;
}
td:nth-child(2){
  flex: 0 0 10%;
  background: Aquamarine;
}
td:nth-child(3){
  flex: 0 0 10%;
  background: pink;
}
<table>
  <tbody>
    <tr>
      <td>Ted</td>
      <td>1</td>
      <td>100%</td>
    </tr>
    <tr>
      <td>Turd Ferguson</td>
      <td>2</td>
      <td>65%</td>
     </tr>
    <tr>
      <td>Hingle McKringleberry</td>
      <td>3</td>
      <td>99%</td>
     </tr>
  </tbody>
</table>

答案 1 :(得分:5)

我认为此问题涉及您的弹性项目的默认display值。

如果使用display: flex覆盖它,则布局应该在浏览器中按预期工作。

进行以下调整:

td:first-child  { display: flex; }
td:nth-child(2) { display: flex; }
td:nth-child(3) { display: flex; }

Revised Codepen

我的第一个想法是确保每个td都应用了display值{ - display: flex-item。但是,flex-item不存在,因此我使用display: flex

修改

上面的解决方案。此编辑与解释有关。

在检查spec时,似乎flex项目甚至没有默认的display值。基本上,一旦您将父级设置为弹性容器,子级就会成为弹性项目,并接受弹性属性,而不管应用了哪个display规则。因此,不需要默认的display规则。

在这种情况下,似乎必须在flex项目上声明display: flex是使Firefox和IE工作所必需的怪癖。