169

I've got a table cell that I would always like to be a particular width. However, it doesn't work with large strings of unspaced text. Here's a test case:

td {
  border: solid green 1px;
  width: 200px;
  overflow: hidden;
}
<table>
  <tbody>
    <tr>
      <td>
        This_is_a_terrible_example_of_thinking_outside_the_box.
      </td>
    </tr>
  </tbody>
</table>

How do I get the text to be cut off at the edge of the box, rather than having the box expand?

12 Answers 12

234

Here is the same problem.

You need to set table-layout:fixed and a suitable width on the table element, as well as overflow:hidden and white-space: nowrap on the table cells.


Examples

Fixed width columns

The width of the table has to be the same (or smaller) than the fixed width cell(s).

With one fixed width column:

* {
  box-sizing: border-box;
}
table {
  table-layout: fixed;
  border-collapse: collapse;
  width: 100%;
  max-width: 100px;
}
td {
  background: #F00;
  padding: 20px;
  overflow: hidden;
  white-space: nowrap;
  width: 100px;
  border: solid 1px #000;
}
<table>
  <tbody>
    <tr>
      <td>
        This_is_a_terrible_example_of_thinking_outside_the_box.
      </td>
    </tr>
    <tr>
      <td>
        This_is_a_terrible_example_of_thinking_outside_the_box.
      </td>
    </tr>
  </tbody>
</table>

With multiple fixed width columns:

* {
  box-sizing: border-box;
}
table {
  table-layout: fixed;
  border-collapse: collapse;
  width: 100%;
  max-width: 200px;
}
td {
  background: #F00;
  padding: 20px;
  overflow: hidden;
  white-space: nowrap;
  width: 100px;
  border: solid 1px #000;
}
<table>
  <tbody>
    <tr>
      <td>
        This_is_a_terrible_example_of_thinking_outside_the_box.
      </td>
      <td>
        This_is_a_terrible_example_of_thinking_outside_the_box.
      </td>
    </tr>
    <tr>
      <td>
        This_is_a_terrible_example_of_thinking_outside_the_box.
      </td>
      <td>
        This_is_a_terrible_example_of_thinking_outside_the_box.
      </td>
    </tr>
  </tbody>
</table>

Fixed and fluid width columns

A width for the table must be set, but any extra width is simply taken by the fluid cell(s).

With multiple columns, fixed width and fluid width:

* {
  box-sizing: border-box;
}
table {
  table-layout: fixed;
  border-collapse: collapse;
  width: 100%;
}
td {
  background: #F00;
  padding: 20px;
  border: solid 1px #000;
}
tr td:first-child {
  overflow: hidden;
  white-space: nowrap;
  width: 100px;
}
<table>
  <tbody>
    <tr>
      <td>
        This_is_a_terrible_example_of_thinking_outside_the_box.
      </td>
      <td>
        This_is_a_terrible_example_of_thinking_outside_the_box.
      </td>
    </tr>
    <tr>
      <td>
        This_is_a_terrible_example_of_thinking_outside_the_box.
      </td>
      <td>
        This_is_a_terrible_example_of_thinking_outside_the_box.
      </td>
    </tr>
  </tbody>
</table>

Sign up to request clarification or add additional context in comments.

1 Comment

I believe table-layout: fixed is not necessary. Setting overflow:hidden and white-space: nowrap on my TDs was sufficient
24

That's just the way TD's are. I believe It may be because the TD element's 'display' property is inherently set to 'table-cell' rather than 'block'.

In your case, the alternative may be to wrap the contents of the TD in a DIV and apply width and overflow to the DIV.

<td style="border: solid green 1px; width:200px;">
    <div style="width:200px; overflow:hidden;">
        This_is_a_terrible_example_of_thinking_outside_the_box.
    </div>
</td>

There may be some padding or cellpadding issues to deal with, and you're better off removing the inline styles and using external css instead, but this should be a start.

1 Comment

This works, but I lose vertical-align:middle and even adding it to the DIV doesn't fix the problem.
12

Apply CSS table-layout:fixed; (and sometimes width:<any px or %>) to the TABLE and white-space: nowrap; overflow: hidden; style on TD. Then set CSS widths on the correct cell or column elements.

Significantly, fixed-layout table column widths are determined by the cell widths in the first row of the table. If there are TH elements in the first row, and widths are applied to TD (and not TH), then the width only applies to the contents of the TD (white-space and overflow may be ignored); the table columns will distribute evenly regardless of the set TD width (because there are no widths specified [on TH in the first row]) and the columns will have [calculated] equal widths; the table will not recalculate the column width based on TD width in subsequent rows. Set the width on the first cell elements the table will encounter.

Alternatively, and the safest way to set column widths is to use <COLGROUP> and <COL> tags in the table with the CSS width set on each fixed width COL. Cell width related CSS plays nicer when the table knows the column widths in advance.

Comments

7

I'm not familiar with the specific issue, but you could stick a div, etc inside the td and set overflow on that.

Comments

7

Best solution is to put a div into table cell with zero width. Tbody table cells will inherit their widths from widths defined the thead. Position:relative and negative margin should do the trick!

Here is a screenshot: https://flic.kr/p/nvRs4j

<body>
<!-- SOME CSS -->
<style>
    .cropped-table-cells,
    .cropped-table-cells tr td { 
        margin:0px;
        padding:0px;
        border-collapse:collapse;
    }
    .cropped-table-cells tr td {
        border:1px solid lightgray;
        padding:3px 5px 3px 5px;
    }
    .no-overflow {
        display:inline-block;
        white-space:nowrap;
        position:relative; /* must be relative */
        width:100%; /* fit to table cell width */
        margin-right:-1000px; /* technically this is a less than zero width object */
        overflow:hidden;
    }
</style>

<!-- CROPPED TABLE BODIES -->
<table class="cropped-table-cells">
    <thead>
        <tr>
            <td style="width:100px;" width="100"><span>ORDER<span></td>
            <td style="width:100px;" width="100"><span>NAME<span></td>
            <td style="width:200px;" width="200"><span>EMAIL</span></td>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td><span class="no-overflow">123</span></td>
            <td><span class="no-overflow">Lorem ipsum dolor sit amet, consectetur adipisicing elit</span></td>
            <td><span class="no-overflow">sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</span></td>
    </tbody>
</table>
</body>

1 Comment

You should use both span and div, of course by having proper block settings for span declared in css. As I know, td should contain div as well.
5

Well here is a solution for you but I don't really understand why it works:

<html><body>
  <div style="width: 200px; border: 1px solid red;">Test</div>
  <div style="width: 200px; border: 1px solid blue; overflow: hidden; height: 1.5em;">My hovercraft is full of eels.  These pretzels are making me thirsty.</div>
  <div style="width: 200px; border: 1px solid yellow; overflow: hidden; height: 1.5em;">
  This_is_a_terrible_example_of_thinking_outside_the_box.
  </div>
  <table style="border: 2px solid black; border-collapse: collapse; width: 200px;"><tr>
   <td style="width:200px; border: 1px solid green; overflow: hidden; height: 1.5em;"><div style="width: 200px; border: 1px solid yellow; overflow: hidden;">
    This_is_a_terrible_example_of_thinking_outside_the_box.
   </div></td>
  </tr></table>
</body></html>

Namely, wrapping the cell contents in a div.

1 Comment

This can be further improved as shown here - specifically, overflow:hidden can be removed from td, and the width of the div can be set to 100% so that it works with any td width (including auto-sized ones!)
5

Easiest and simplest solution that works:

table { table-layout: fixed }

table td {     
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis; 
}

Comments

3

You'll have to set the table's style attributes: width and table-layout: fixed; to let the 'overflow: hidden;' attribute work properly.

Imo this works better then using divs with the width style attribute, especially when using it for dynamic resizing calculations, the table will have a simpler DOM which makes manipulation easier because corrections for padding and margin are not required

As an extra, you don't have to set the width for all cells but only for the cells in the first row.

Like this:

<table style="width:0px;table-layout:fixed">
<tr>
    <td style="width:60px;">
        Id
    </td>
    <td style="width:100px;">
        Name
    </td>
    <td style="width:160px;overflow:hidden">
        VeryLongTextWhichShouldBeKindOfTruncated
    </td>
</tr>
<tr>
    <td style="">
        Id
    </td>
    <td style="">
        Name
    </td>
    <td style="overflow:hidden">
        VeryLongTextWhichShouldBeKindOfTruncated
    </td>
</tr>
</table>

Comments

2

I've just had a similar problem, and had to use the <div> inside the <td> at first (John MacIntyre's solution didn't work for me for various reasons).

Note though that <td><div>...</div></td> isn't valid placement for a div so instead I'm using a <span> with display:block; set. It validates fine now and works.

Comments

1
<style>
    .col {display:table-cell;max-width:50px;width:50px;overflow:hidden;white-space: nowrap;}
</style>
<table>
    <tr>
        <td class="col">123456789123456789</td>
    </tr>
</table>

displays 123456

Comments

1

Use max-width on your <td>

To my biggest surprise, today it works out of the box, without additional div embedding or other fancy tricks. You can just use max-width to limit the width in pixels and it will nicely cut your text with an ellipsis at the end:


    td {
        white-space:nowrap;
        overflow:hidden;
        text-overflow:ellipsis;
        max-width:500px;      
    }

What happens is demonstrated here: https://codepen.io/dkellner/pen/ExzNdKb

This was painfully missing for decades.
Not sure when it changed but this is 2024 and it works.

4 Comments

I don't see this working out of the box. Can you please provide an example to show that it works out of the box?
Okay... the secret sauce is using the max-width instead of the width style to set the width. Could you please add more details and an example to your answer it would be more useful. Cheers
@ImanMahmoudinasab – something like this?
0

to make more simple i propose to put an textarea inside the td wich is manage automaticly the overflow

<td><textarea autofocus>$post_title</textarea></td>

need to be ameliorate

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.