How to get the <td> in HTML tables to fit content, and let a specific <td> fill in the rest

HtmlCssHtml TableWidth

Html Problem Overview


This is a hypothetical example:

table, thead, tbody, tr { width: 100%; }
    table { table-layout: fixed }
    table > thead > tr > th { width: auto; }

<table>
      <thead>
        <tr>
          <th>Column A</th>
          <th>Column B</th>
          <th>Column C</th>
          <th class="absorbing-column">Column D</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td>Data A.1 lorem</td>
          <td>Data B.1 ip</td>
          <td>Data C.1 sum l</td>
          <td>Data D.1</td>
        </tr>
        <tr>
          <td>Data A.2 ipsum</td>
          <td>Data B.2 lorem</td>
          <td>Data C.2 some data</td>
          <td>Data D.2 a long line of text that is long</td>
        </tr>
        <tr>
          <td>Data A.3</td>
          <td>Data B.3</td>
          <td>Data C.3</td>
          <td>Data D.3</td>
        </tr>
      </tbody>
    </table>

I want to have every single column's width to fit its content size, and leave the rest of the space for the one column with the "absorbing-column" class, so that it looks like this:

| HTML                                                                   | 100%
| body                                                                   | 100%
| table                                                                  | 100%
|------------------------------------------------------------------------|
| Column A | Column B       | Column C | Column D                        |
|------------------------------------------------------------------------|
| Column A | Column B lorem | Column C | Column D                        |
| Column A | Column B       | Column C | Column D                        |
| Column A | Column B       | Column C | Column D                        |
|------------------------------------------------------------------------|

You see, Column B is a bit bigger than the rest due to the extra data in the first row, but Column D always uses up the remaining space.

I played around with max-width, min-width, auto, etc. and could not figure out how to make this work.

In other words, I want all columns to take whatever width they need and not more, and then I want Column D to use up all of the remaining space inside the 100% width table.

Html Solutions


Solution 1 - Html

Define width of .absorbing-column

Set table-layout to auto and define an extreme width on .absorbing-column.

Here I have set the width to 100% because it ensures that this column will take the maximum amount of space allowed, while the columns with no defined width will reduce to fit their content and no further.

This is one of the quirky benefits of how tables behave. The table-layout: auto algorithm is mathematically forgiving.

You may even choose to define a min-width on all td elements to prevent them from becoming too narrow and the table will behave nicely.

table {
    table-layout: auto;
    border-collapse: collapse;
    width: 100%;
}
table td {
    border: 1px solid #ccc;
}
table .absorbing-column {
    width: 100%;
}

<table>
  <thead>
    <tr>
      <th>Column A</th>
      <th>Column B</th>
      <th>Column C</th>
      <th class="absorbing-column">Column D</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Data A.1 lorem</td>
      <td>Data B.1 ip</td>
      <td>Data C.1 sum l</td>
      <td>Data D.1</td>
    </tr>
    <tr>
      <td>Data A.2 ipsum</td>
      <td>Data B.2 lorem</td>
      <td>Data C.2 some data</td>
      <td>Data D.2 a long line of text that is long</td>
    </tr>
    <tr>
      <td>Data A.3</td>
      <td>Data B.3</td>
      <td>Data C.3</td>
      <td>Data D.3</td>
    </tr>
  </tbody>
</table>

Solution 2 - Html

demo - http://jsfiddle.net/victor_007/ywevz8ra/

added border for better view (testing)

more info about white-space

table{
    width:100%;
}
table td{
    white-space: nowrap;  /** added **/
}
table td:last-child{
    width:100%;
}

    table {
      width: 100%;
    }
    table td {
      white-space: nowrap;
    }
    table td:last-child {
      width: 100%;
    }

<table border="1">
  <thead>
    <tr>
      <th>Column A</th>
      <th>Column B</th>
      <th>Column C</th>
      <th class="absorbing-column">Column D</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Data A.1 lorem</td>
      <td>Data B.1 ip</td>
      <td>Data C.1 sum l</td>
      <td>Data D.1</td>
    </tr>
    <tr>
      <td>Data A.2 ipsum</td>
      <td>Data B.2 lorem</td>
      <td>Data C.2 some data</td>
      <td>Data D.2 a long line of text that is long</td>
    </tr>
    <tr>
      <td>Data A.3</td>
      <td>Data B.3</td>
      <td>Data C.3</td>
      <td>Data D.3</td>
    </tr>
  </tbody>
</table>

Solution 3 - Html

Setting CSS width to 1% or 100% of an element according to all specs I could find out is related to the parent. Although Blink Rendering Engine (Chrome) and Gecko (Firefox) at the moment of writing seems to handle that 1% or 100% (make a columns shrink or a column to fill available space) well, it is not guaranteed according to all CSS specifications I could find to render it properly.

One option is to replace table with CSS4 flex divs:

https://css-tricks.com/snippets/css/a-guide-to-flexbox/

That works in new browsers i.e. IE11+ see table at the bottom of the article.

Solution 4 - Html

use overflow:

overflow: visible;

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser2985898View Question on Stackoverflow
Solution 1 - HtmlgfullamView Answer on Stackoverflow
Solution 2 - HtmlVitorino fernandesView Answer on Stackoverflow
Solution 3 - HtmlMladen AdamovicView Answer on Stackoverflow
Solution 4 - HtmlDonnie Gallocanta Jr.View Answer on Stackoverflow