394

Given the following markup, how could I use CSS to force one cell (all cells in column) to fit to the width of the content within it rather than stretch (which is the default behaviour)?

td.block {
  border: 1px solid black;
}
<table style="width: 100%;">
  <tr>
    <td class="block">this should stretch</td>
    <td class="block">this should stretch</td>
    <td class="block">this should be the content width</td>
  </tr>
</table>

I realize I could hard code the width, but I'd rather not do that, as the content which will go in that column is dynamic.

Looking at the image below, the first image is what the markup produces. The second image is what I want.

enter image description here

isherwood
  • 58,414
  • 16
  • 114
  • 157
Mansfield
  • 14,445
  • 18
  • 76
  • 112
  • Possible duplicate of [CSS table column autowidth](https://stackoverflow.com/questions/4757844/css-table-column-autowidth) – Vadzim Jun 24 '17 at 12:00

8 Answers8

628

I'm not sure if I understand your question, but I'll take a stab at it:

td {
    border: 1px solid #000;
}

tr td:last-child {
    width: 1%;
    white-space: nowrap;
}
<table style="width: 100%;">
    <tr>
        <td class="block">this should stretch</td>
        <td class="block">this should stretch</td>
        <td class="block">this should be the content width</td>
    </tr>
</table>
Danny Beckett
  • 20,529
  • 24
  • 107
  • 134
MetalFrog
  • 9,943
  • 1
  • 22
  • 24
  • 3
    why you write `` instead of `
    `
    – xkeshav Jun 29 '12 at 18:45
  • 22
    @diEcho I didn't write that part, that was from the example code. Regardless, it is bad practice to use the width attribute on elements. In this quick example, the inline CSS is fine, but it should be abstracted into a file if this was production-level code. – MetalFrog Jun 29 '12 at 19:29
  • 52
    A cleaner way to do this IMO would be to define a style called "nostretch" (or something like that), and then just define nostretch in the CSS to have width:1% and the nowrap. Then the last TD would have 'class="nostretch block"'. That way you can "nostretch" any cell you want. – Tim Holt Feb 07 '13 at 18:00
  • 3
    This is a good solution, but sadly, in Bootstrap 3 my button groups will wrap from this: http://jsfiddle.net/wexdX/326/ Any ideas how I can suppress it? – Martin Braun Apr 20 '14 at 21:40
  • 1
    @modiX Only thing that seems to work is setting a min-width on `.btn-group`. Seems like there has to be a better solution. Might want to start your own question. http://jsfiddle.net/wexdX/337/ – MetalFrog Apr 22 '14 at 04:12
  • @EakanGopalakrishnan The buttons are stacked in your jsfiddle. The goal was to have them side-by-side. – MetalFrog Jul 31 '14 at 02:23
  • Not sure how that happened. probably didn't update my link. http://jsfiddle.net/wexdX/499/ – Eakan Gopalakrishnan Jul 31 '14 at 08:48
  • What about this case: I apply the nostretch style to td's, but the width of my th is bigger. The class does not work for th tags:$ Does anyone know a solution for this? – Niek Nijland Feb 10 '15 at 08:41
  • 7
    This only works when the content is wider then width:1% - right? Because if the content is smaller then width:1%, the cell will be larger. – Adam Feb 03 '16 at 10:56
  • 2
    @Adam Yes, interesting is to also know , that this **also works the other way around** - you can set "absorbing" column (which is often wanted) to have 100% width , props to => http://stackoverflow.com/a/26915414/1835470 – jave.web Feb 01 '17 at 14:18
  • 3
    In my testing, this doesn't work the other way around, and using `1px` is better than `1%`. – NetMage Jul 11 '18 at 21:49
  • ⚠ does not work with "table-layout: fixed;" !!! https://developer.mozilla.org/en-US/docs/Web/CSS/table-layout – Luckylooke Mar 01 '22 at 15:54
  • Would 1px work? 1% is arbitrarily small (or large even) IMO. – iMe Jul 16 '22 at 06:53
74

Setting

max-width:100%;
white-space:nowrap;

will solve your problem.

Jason
  • 15,017
  • 23
  • 85
  • 116
Shubham Nigam
  • 3,844
  • 19
  • 32
20

For me, this is the best autofit and autoresize for table and its columns (use css !important ... only if you can't without)

.myclass table {
    table-layout: auto !important;
}

.myclass th, .myclass td, .myclass thead th, .myclass tbody td, .myclass tfoot td, .myclass tfoot th {
    width: auto !important;
}

Don't specify css width for table or for table columns. If table content is larger it will go over screen size to.

TmTron
  • 17,012
  • 10
  • 94
  • 142
Cristian Florescu
  • 1,660
  • 20
  • 24
10

There are many ways to do this!

correct me if I'm wrong but the question is looking for this kind of result.

<table style="white-space:nowrap;width:100%;">
  <tr>
    <td class="block" style="width:50%">this should stretch</td>
    <td class="block" style="width:50%">this should stretch</td>
    <td class="block" style="width:auto">this should be the content width</td>
  </tr>
</table>

The first 2 fields will "share" the remaining page (NOTE: if you add more text to either 50% fields it will take more space), and the last field will dominate the table constantly.

If you are happy to let text wrap you can move white-space:nowrap; to the style of the 3rd field
will be the only way to start a new line in that field.

alternatively, you can set a length on the last field ie. width:150px, and leave percentage's on the first 2 fields.

Hope this helps!

isherwood
  • 58,414
  • 16
  • 114
  • 157
5

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.

Mladen Adamovic
  • 3,071
  • 2
  • 29
  • 44
5

First, setting

td {
  max-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}

ensures that your your table cells will stretch.

Now you only need

td.fit {
  width: 0;
  min-width: fit-content;
}

on your fitting cells.

Note that now the table will only overflow in width if content of all fitting cells is too much to fit into a table-width of 100%.

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

td {
  border: 1px solid black;
}

td {
  max-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}

td.fit {
  width: 0;
  min-width: fit-content;
}
<table>
  <tr>
    <td class="stretch">this should stretch</td>
    <td class="stretch">this should stretch</td>
    <td class="fit">this should be the content width</td>
  </tr>
</table>
DonFuchs
  • 371
  • 2
  • 14
0

For some scenarios, this may work for you. One that I came across was when I need all the td tags to fit the content. Leaving rest of the horizontal space empty. Here's what I did:

table {
  width: 100%;
  background-color: Cornflowerblue;
}

td {
  border: 1px solid lightyellow;
  white-space: nowrap;
}

td:last-child {
  width: 100%;
  /*hiding border*/
  border: none;
}
<table>
  <tr>
    <td>
      Content 1
    </td>
    <td>
      Content 2
    </td>
    <td>
    </td>
  </tr>
</table>
raghav-wd
  • 410
  • 4
  • 12
-8

Simple :

    <div style='overflow-x:scroll;overflow-y:scroll;width:100%;height:100%'>
Parth Jani
  • 33
  • 1
  • 4
  • 12
  • 11
    Don't see how this answer is relevant at all to this 8 year old question. I'ts a `
    `, the question was about tables. And your answer doesn't make the column cells width shrink to its content.
    – Jonas Sandstedt Nov 17 '20 at 19:14