Flex CSS property in doesn't work on I

2020-04-07 12:00发布

问题:

I'm looking for a solution how to make the Flex property work on a table component across all three browsers (IE, Firefox and Chrome).

The following code works only on Chrome (even though -ms- and -webkit- prefixes added):

table {
  background-color: white;
}
.child {
  padding: 5px;
  margin: 5px;
  background-color: #eee;
  border: 3px solid;
}
.container {
  padding: 2px;
  background-color: yellow;
  display: -ms-flexbox;
  display: -webkit-flex;
  display: flex;
  -webkit-flex-direction: row;
  -ms-flex-direction: row;
  flex-direction: row;
  -webkit-flex-wrap: wrap;
  -ms-flex-wrap: wrap;
  flex-wrap: wrap;
  -webkit-justify-content: space-between;
  -ms-flex-pack: justify;
  justify-content: space-between;
  -webkit-align-content: center;
  -ms-flex-line-pack: center;
  align-content: center;
  -webkit-align-items: stretch;
  -ms-flex-align: stretch;
  align-items: stretch;
}
.child.one {
  color: green;
  -webkit-order: 1;
  -ms-flex-order: 1;
  order: 1;
}
.child.two {
  color: purple;
  -webkit-order: 2;
  -ms-flex-order: 2;
  order: 2;
  flex-shrink: 0;
}
.child.three {
  color: red;
  -webkit-order: 3;
  -ms-flex-order: 3;
  order: 3;
}
<table style="width:100%">
  <tbody>
    <tr class="container">
      <td class="child one" align="left">
        One
      </td>
      <td class="child two" align="center">
        Two.
        <br>Lorem ipsum
        <br>dolor sit amet
        <br>This is a bit longer line
      </td>
      <td class="child three" align="right">
        Three
      </td>
    </tr>
  </tbody>
</table>

Please look the code in fiddle: http://jsfiddle.net/ax961ys1/

回答1:

This would appear to be due to each .child element being display: table-cell; by default (expected as these are indeed table cells!).

In Chrome when you use the flexbox model on .container the .child elements are automatically converted into display: block; which enables flexbox to work.

In Firefox and IE the .child elements remain as display: table-cell;.

The latest W3C draft for the CSS Flexible Box Layout Module states:

The display value of a flex item is blockified: if the specified display of an in-flow child of an element generating a flex container is an inline-level value, it computes to its block-level equivalent. (See CSS2.1§9.7 [CSS21] and CSS Display [CSS3-DISPLAY] for details on this type of display value conversion.)

Flex Items (https://drafts.csswg.org/css-flexbox-1/#flex-items)

This suggests that flex items should be changed to its block-level equivalent (if it isn't already a block-level element).

The draft goes further and states:

Some values of display normally trigger the creation of anonymous boxes around the original box. If such a box is a flex item, it is blockified first, and so anonymous box creation will not happen. For example, two contiguous flex items with display: table-cell will become two separate display: block flex items, instead of being wrapped into a single anonymous table.

Flex Items (https://drafts.csswg.org/css-flexbox-1/#flex-items)

In this instance it appears that this is something that Chrome is doing but IE and Firefox are not. The presence of the anonymous table and the fact that the .child elements are not blockified would seem to be the cause of the behaviour.

To obtain the same result in Chrome, IE and Firefox:

  • Add display: block; to .child
  • To ensure the .child elements wrap correctly in IE add display: block; to table and tbody

table {
  background-color: white;
  display: block; /*Required for wrap to work correctly in IE*/
}
tbody {
  display: block; /*Required for wrap to work correctly in IE*/
}
.child {
  padding: 5px;
  margin: 5px;
  background-color: #eee;
  border: 3px solid;
  display: block;
}
.container {
  padding: 2px;
  background-color: yellow;
  display: -ms-flexbox;
  display: -webkit-flex;
  display: flex;
  -webkit-flex-direction: row;
  -ms-flex-direction: row;
  flex-direction: row;
  -webkit-flex-wrap: wrap;
  -ms-flex-wrap: wrap;
  flex-wrap: wrap;
  -webkit-justify-content: space-between;
  -ms-flex-pack: justify;
  justify-content: space-between;
  -webkit-align-content: center;
  -ms-flex-line-pack: center;
  align-content: center;
  -webkit-align-items: stretch;
  -ms-flex-align: stretch;
  align-items: stretch;
}
.child.one {
  color: green;
  -webkit-order: 1;
  -ms-flex-order: 1;
  order: 1;
}
.child.two {
  color: purple;
  -webkit-order: 2;
  -ms-flex-order: 2;
  order: 2;
  flex-shrink: 0;
}
.child.three {
  color: red;
  -webkit-order: 3;
  -ms-flex-order: 3;
  order: 3;
}
<table style="width:100%">
  <tbody>
    <tr class="container">
      <td class="child one" align="left">
        One
      </td>
      <td class="child two" align="center">
        Two.
        <br>Lorem ipsum
        <br>dolor sit amet
        <br>This is a bit longer line
      </td>
      <td class="child three" align="right">
        Three
      </td>
    </tr>
  </tbody>
</table>