9

I have an HTML table (generated by an MVC WebGrid) that is 5 columns across. What I want is the first 4 columns to take up 100% of the width and the 5th column to sit underneath also taking up 100% of the width.

  <tr>
    <td class="date">13/05/2015 13:40:55</td>
    <td class="firstname">Bob</td>
    <td class="lastname">Reed</td>
    <td class="errors"></td>
    <td class="profile">This is a lot of content that could potentially screw up the table layout if it were to be sat on the same row as the other 4 columns</td>
  </tr>

There is accompanying CSS, but it doesn't have any relevance to the table layout.

I've got to admit I'm pretty much stumped. I've tried searching, but all I seem to find are questions about using the display:table / table-row / table-cell CSS properties on either div or list elements.

Is what I'm trying to do possible using only CSS to modify the current HTML, or is it likely to take a complete re-write of the HTML structure (and thus probably dropping the WebGrid) to get it to display how I want?

Dark Hippo
  • 1,255
  • 2
  • 15
  • 35
  • I don't think this is possible, without using JS to remove the cell from the `tr` and putting it in another `tr` below. – evolutionxbox May 13 '15 at 14:11
  • 1
    I'm with @evolutionxbox on this. Can't you just edit the templates of the WebGrid and change the table to divs? – timgavin May 13 '15 at 14:12
  • I actually don't know, I don't have that much experience with WebGrids. I was trying to avoid that as it'll mean essentially re-doing the whole structure of the table in question, but I'm starting to think that may be the only way – Dark Hippo May 13 '15 at 14:20

2 Answers2

13

You may try to reset the display properties of table elements and use the flex model:

table,
tbody {
  display:inline-block;/* whatever, just  reset table layout display to go further */
}
td {
  border:solid 1px;
}
tr {
  display:flex;
  flex-wrap:wrap; /* allow to wrap on multiple rows */
}
td {
  display:block;
  flex:1 /* to evenly distributs flex elements */
}
.date, .profile {
  width:100%; /* fill entire width,row */
  flex:auto; /* reset the flex properti to allow width take over */
}
<table>
  <tr>
    <td class="date">13/05/2015 13:40:55</td>
    <td class="firstname">Bob</td>
    <td class="lastname">Reed</td>
    <td class="errors"></td>
    <td class="profile">This is a lot of content that could potentially screw up the table layout if it were to be sat on the same row as the other 4 columns</td>
  </tr>
</table>

Not too sure that each browsers will accept this the same ways. codepen to play with : http://codepen.io/anon/pen/WvwpQq

to stack tds, then display:block:

td {
  border:1px solid;
  display:block;
  } 
    <table>
      <tr>
        <td class="date">13/05/2015 13:40:55</td>
        <td class="firstname">Bob</td>
        <td class="lastname">Reed</td>
        <td class="errors"></td>
        <td class="profile">This is a lot of content that could potentially screw up the table layout if it were to be sat on the same row as the other 4 columns</td>
      </tr>
    </table>
G-Cyrillus
  • 101,410
  • 14
  • 105
  • 129
  • you know, I read a lot about mimicking a table layout by setting the display properties of a list, but it never occurred to me to try resetting the display properties of the table elements. Awesome idea, I'll give it a try now – Dark Hippo May 13 '15 at 14:30
  • Works like a charm (on Chrome anyway, now to get it working on the other browsers). Thanks for the help, much appreciated – Dark Hippo May 13 '15 at 14:45
  • 2
    For anyone interested I have tested both snippets above in a couple of browsers: FF 53: Works fine ; Chromium 58: Works fine ; Chrome on Android 7 (Galaxy S7): Works fine (could only test codepen) ; Chrome on Android 4.4 (Nexus 5): Works fine (could only test codepen) ; Safari on IOS 10.3 (iPad Pro emulated): Works fine ; Safari on IOS 9 (iPhone 6): Works fine (could only test codepen) ; IE 11: Works mostly fine. In the first example, the text in the last cell does not break in two lines, you get a scrollbar instead. I'm sure the IE11 issue can be worked around if need be. – Alice Heaton Aug 02 '17 at 16:48
  • 1
    @AliceHeaton thanks so much for the feedback. For IE11, i would give a try to max-width:100% for table/tbody along display:block; – G-Cyrillus Aug 02 '17 at 16:53
  • That is just brilliant! Thanks so much! – Ewout Sep 05 '18 at 10:29
0

It is possible to use display: contents and keep it as a table if you limit yourself to one child (like a text node or an element, but actually in CSS box terms) in the 5th cell (could be also 4th if you change before to after).

.profile {
    display: contents;
.profile::before {
    content: "";
    display: table-row;
}
ByteEater
  • 885
  • 4
  • 13