2

In my project I need to manipulate a standard table to act in a certain way. I need the <td> to be both columns and rows, depending on content and resolution (responsiveness).

So far it's working in Chrome and FF, but it's completely messed up in IE, and I'm not having any luck in trying to figure out why.

Here's my code:

body {
  color: #fff;
}
table,
.line2,
.line3 {
  width: 100%;
}
tr {
  display: flex;
  flex-flow: row wrap;
}
td {
  margin: 1px;
}
.line1 {
  background: red;
  flex: 1;
}
.line2,
.line3 {
  background: blue;
}
.line3 {
  background: green;
}
<table>
  <tr>
    <td class="line1">line 1</td>
    <td class="line1">line 1</td>
    <td class="line1">line 1</td>
    <td class="line1">line 1</td>
    <td class="line2">line 2</td>
    <td class="line3">line 3</td>
  </tr>
</table>

What I want is all line1's to be columns and line2/3 to be rows below.

However, in IE11 (and I'm assuming below) they just all stack up as columns, completely messing it up.

I've looked at https://github.com/philipwalton/flexbugs but haven't been able to find a solution.

What am I doing wrong? Does this just not work in IE?

Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
Trace DeCoy
  • 649
  • 6
  • 16

2 Answers2

3

As you know, IE11 is known for having many "flex bugs" (details).

As an example, the flex property, which is in your code, has multiple rendering problems (details).

And in this particular case, using HTML table elements appears to be adding to the confusion, and IE11 just doesn't know what to do. More specifically, IE11 is having trouble recognizing flex properties on table elements.

You also need to consider the tbody element, which isn't necessary for you to include, but which the browser automatically adds to your HTML structure (because tbody is required by the spec). This throws off the flex formatting context, because the parent-child relationship is essential.

What seems to work in IE11 (and the other major browsers) is specifying flex layout at every level:

table {
  display: flex;
  width: 100%;
}
tbody {
  display: flex;
  flex-basis: 100%;
}
tr {
  display: flex;
  flex-basis: 100%;
  flex-flow: row wrap;
}
td {
  display: flex;
  flex-basis: 100%;
  flex-shrink: 0;
  margin: 1px;
}
.line1 { 
  flex-basis: 0; 
  flex: 1;
}
.line1 { background: red; }
.line2 { background: blue; }
.line3 { background: green; }
body { color: #fff; }
<table>
  <tr>
    <td class="line1">line 1</td>
    <td class="line1">line 1</td>
    <td class="line1">line 1</td>
    <td class="line1">line 1</td>
    <td class="line2">line 2</td>
    <td class="line3">line 3</td>
  </tr>
</table>

jsFiddle

Community
  • 1
  • 1
Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
1

thanks for your effort and time -- especially Michael_B.

However, I found an easier, and likely more appropriate, solution. It's to simply give the <td>'s a display: block;

So no need to give every single element the flex attribute.

Regarding if I need the <tbody> -- I realize the browser adds it, however I need it in place to add ListJS (js sorting) as it requires the class="list"

Trace DeCoy
  • 649
  • 6
  • 16
  • You're right. In that convoluted mess of bugs, quirks and varied implementations, your solution is simple and it works. Great discovery. Just bear in mind that proper implementation of [*flex layout requires any specified `display` value on flex items to be ignored*](https://www.w3.org/TR/css-flexbox-1/#flex-items). – Michael Benjamin Apr 15 '17 at 22:42