Search code examples
htmlcsshtml-table

How to make the last column of a table fill the remaining space?


I have a table with a fixed width and I want the size of all columns to be automatically adjusted to their content. However, if there is little content for the columns, I want only the last column to fill the remaining space. So basically, I want the table to behave like a normal table with no fixed width. In cases where the table does not fill the maximum width of the parent, the last column should expand. Furthermore, the table should have several rows, where the cells of the same column are exactly below each other.

Here are some examples of how the table is supposed to look:

 -----------------------------------------------------------------------
| Lorem ipsum | Lorem ipsum | Lorem ipsum                               |
 -----------------------------------------------------------------------
 -----------------------------------------------------------------------
| Lorem ipsum dolor sit amet | Lorem | Lorem ipsum dolor sit            |
 -----------------------------------------------------------------------
 -----------------------------------------------------------------------
| Lorem ipsum dolor sit | Lorem ipsum dolor sit | Lorem ipsum dolor sit |
 -----------------------------------------------------------------------
 -----------------------------------------------------------------------
| Lorem ipsum dolor sit | Lorem ipsum dolor sit | Lorem ipsum dolor sit |
| amet, consetetur      | amet, consetetur      | amet, consetetur      |
 -----------------------------------------------------------------------

The best solution I have found so far (other question on stackoverflow) uses width: 100%; on the table and the last cell and white-space: nowrap; on all cells. Problem with the solution is that the table becomes wider than it should because of the white-space: nowrap; when there is a lot of text, as you can see in the example:

div {
  width: 500px;
  background-color: #cccccc;
  padding: 10px;
}

table {
  border-collapse: collapse;
  width: 100%;
}

td {
  border: 1px solid black;
  padding: 5px;
  white-space: nowrap;
}

td:last-child {
  width: 100%;
}
<div>
  <p>This looks good:</p>
  <table>
    <tr><td>Lorem ipsum</td><td>Lorem ipsum</td><td>Lorem ipsum</td></tr>
  </table>
  <p>This doesn't:</p>
  <table>
    <tr>
      <td>Lorem ipsum dolor sit amet, consetetur</td>
      <td>Lorem ipsum dolor sit amet, consetetur</td>
      <td>Lorem ipsum dolor sit amet, consetetur</td>
    </tr>
  </table>
</div>

I have written my own answer using JS (see below). However, I would prefer a solution without JS.


Solution

  • I have now come up with my own solution using Javascript:

    let tables = document.getElementsByTagName("table");
    for (table of tables) {
      let tableCs = getComputedStyle(table);
      let tableWidth = parseFloat(tableCs.width) + parseFloat(tableCs.marginLeft) + parseFloat(tableCs.marginRight);
    
      let parentCs = getComputedStyle(table.parentElement);
      let parentWidth = table.parentElement.offsetWidth - parseFloat(parentCs.paddingLeft) - parseFloat(parentCs.paddingRight);
      let remainingSpace = parentWidth - tableWidth;
    
      let cell = table.querySelector("td:last-child");
      if (cell && remainingSpace) {
        cell.style.width = (parseFloat(getComputedStyle(cell).width) + remainingSpace) + "px";
      }
    }
    div {
      width: 500px;
      background-color: #cccccc;
      padding: 10px;
    }
    
    table {
      border-collapse: collapse;
    }
    
    td {
      border: 1px solid black;
      padding: 5px;
    }
    <div>
      <table>
        <tr><td>Lorem ipsum </td><td>Lorem</td><td>Lorem ipsum dolor</td></tr>
      </table>
      <br>
      <table>
        <tr><td>Lorem ipsum dolor sit amet, consetetur sadipscing elitr</td><td>Lorem ipsum dolor sit amet, consetetur sadipscing elitr</td><td>Lorem ipsum dolor sit amet, consetetur sadipscing elitr</td></tr>
      </table>
      <br>
      <table>
        <tr><td>Lorem ipsum</td><td>Lorem ipsum dolor</td><td>Lorem ipsum dolor sit amet, consetetur sadipscing elitr</td></tr>
      </table>
    </div>