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

本秂侑毒 提交于 2020-01-20 13:30:06

问题


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.


回答1:


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>



回答2:


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>



回答3:


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.




回答4:


use overflow:

overflow: visible;


来源:https://stackoverflow.com/questions/26915087/how-to-get-the-td-in-html-tables-to-fit-content-and-let-a-specific-td-fill

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!