Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CSS: Constrain a table with long cell contents to page width?

Tags:

Take the following CSS+HTML:

<style>     div.stuff {         overflow: hidden;         width: 100%;         white-space: nowrap;     }     table { width: 100%; }     td { border: 1px dotted black; } </style>  <table>     <tr><td>         <div class='stuff'>Long text long text long text long text long text long text long text long text long text long text long text long text long text long text long text long text long text long text</div>     </td></tr> </table> 

This causes the table to grow to accommodate the entire long text. (Make your browser window smaller to see if you have a humongous screen resolution.)

I added width: 100% and overflow: hidden to indicate that the long text should simply be cut off, but it seems to ignore that. How do I constrain the table/the table cell/the div in such a way that the table’s width does not exceed the width of the document?

(Please don’t comment on the merits of using a table at all. I am indeed displaying tabular data, so the use of a table is semantically correct. Also please don’t question the user-friendliness of cutting off the text; there is actually an “expand” button that allows the user to view the full contents. Thanks!)

(Edit: I tried max-width too, to no avail.)

like image 355
Timwi Avatar asked Sep 27 '11 12:09

Timwi


2 Answers

To achieve this, you have to wrap the long text into two divs. The outer one gets position: relative and contains only the inner one. The inner one gets position: absolute, overflow: hidden, and width: 100% (this constrains it to the size of the table cell).

The table-layout algorithm now considers those table cells empty (because absolutely-positioned elements are excluded from layout calculations). Therefore we have to tell it to grow that column regardless. Interestingly, setting width: 100% on the relevant <col> element works, in the sense that it doesn’t actually fill 100% of the width, but 100% minus the width of all the other columns (which are automatically-sized). It also needs a vertical-align: top as otherwise the (empty) outer div is aligned middle, so the absolutely-positioned element will be off by half a line.

Here is a full example with a three-column, two-row table showing this at work:

CSS:

div.outer {     position: relative; } div.inner {     overflow: hidden;     white-space: nowrap;     position: absolute;     width: 100%; } table {     width: 100%;     border-collapse: collapse; } td {     border: 1px dotted black;     vertical-align: top; } col.fill-the-rest { width: 100%; } 

HTML:

<table>     <col><col><col class="fill-the-rest">     <tr>         <td>foo</td>         <td>fooofooooofooooo</td>         <td>             <div class='outer'>                 <div class='inner'>                     Long text long text long text long text long text long text long text long text long text long text long text long text long text long text long text long text long text long text                 </div>             </div>         </td>     </tr>     <tr>         <td>barbarbarbarbar</td>         <td>bar</td>         <td>             <div class='outer'>                 <div class='inner'>                     Some more long text Some more long text Some more long text Some more long text Some more long text Some more long text Some more long text Some more long text Some more long text Some more long text Some more long text Some more long text Some more long text Some more long text Some more long text Some more long text Some more long text Some more long text                 </div>             </div>         </td>     </tr> </table> 

In this example, the first two columns will have the minimum possible size (i.e. spaces will make them wrap a lot unless you also add white-space: nowrap to them).

jsFiddle: http://jsfiddle.net/jLX4q/

like image 90
Timwi Avatar answered Sep 20 '22 14:09

Timwi


I added width: 100% and overflow: hidden to indicate that the long text should simply be cut off, but it seems to ignore that.

It's not ignoring that, your div is expanding 100% the width of your table, which is set to expand 100% as it is, just give your td a max-width and it should cutoff as you expect.

like image 33
Andres Ilich Avatar answered Sep 17 '22 14:09

Andres Ilich