Reputation: 28743
I want to use CSS text-overflow
in a table cell, such that if the text is too long to fit on one line, it will clip with an ellipsis instead of wrapping to multiple lines. Is this possible?
I tried this:
td {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
But the white-space: nowrap
seems to make the text (and its cell) continually expand out to the right, pushing the total width of the table beyond the width of its container. Without it, however, the text continues to wrap to multiple lines when it hits the edge of the cell.
Upvotes: 688
Views: 683712
Reputation: 1745
what worked fine for me is this simple code. By playing with number of character you can get the dots in almost any td you want
table *{
max-width: 50ch;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
}
Upvotes: 0
Reputation: 8255
If you can ditch the table tags, then modern CSS has a much cleaner (IMO) solution available: using the grid
layout.
You simply need one div
or similar to represent the table, with cells inside, e.g.:
<div class="table">
<div class="cell">text</div>
<div class="cell">text</div>
<div class="cell">text</div>
<div class="cell">text</div>
</div>
Now if I want this to be a 2x2 table then it's simply a case of defining two auto sized columns for the grid:
.table {
display: grid;
grid-template-columns: auto auto;
}
For the cells you simply need a few more lines of CSS:
.cell {
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
}
Job done! If you need to ensure some columns are wider than others then using the fr
units or other available options for the columns template works well.
.table {
display: grid;
grid-template-columns: auto auto;
}
.cell {
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
border: 1px solid black;
}
<div class="table">
<div class="cell">long long long long long long long long long long long long long long long long long long long long long long long long</div>
<div class="cell">text</div>
<div class="cell">text</div>
<div class="cell">text</div>
</div>
Upvotes: 4
Reputation: 13729
<td><div>Your overflowing content here.</div></td>
td div
{
max-height: 30vh;
overflow: auto;
}
Trying to mess with the overall table
for this very specific purpose makes no sense. Yes, sometimes it is okay to add an extra element if you explicitly work to not be another 600-divs-nested Twitter/Facebook "developer".
Upvotes: 0
Reputation: 9072
Specifying a max-width
or fixed width doesn't work for all situations, and the table should be fluid and auto-space its cells. That's what tables are for. Works on IE9 and other browsers.
Use this: http://jsfiddle.net/maruxa1j/
table {
width: 100%;
}
.first {
width: 50%;
}
.ellipsis {
position: relative;
}
.ellipsis:before {
content: ' ';
visibility: hidden;
}
.ellipsis span {
position: absolute;
left: 0;
right: 0;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
<table border="1">
<thead>
<tr>
<th>Header 1</th>
<th>Header 2</th>
<th>Header 3</th>
<th>Header 4</th>
</tr>
</thead>
<tbody>
<tr>
<td class="ellipsis first"><span>This Text Overflows and is too large for its cell.</span></td>
<td class="ellipsis"><span>This Text Overflows and is too large for its cell.</span></td>
<td class="ellipsis"><span>This Text Overflows and is too large for its cell.</span></td>
<td class="ellipsis"><span>This Text Overflows and is too large for its cell.</span></td>
</tr>
</tbody>
</table>
Upvotes: 133
Reputation: 169
It is worked for me
table {
width: 100%;
table-layout: fixed;
}
td {
text-overflow: ellipsis;
white-space: nowrap;
}
Upvotes: 5
Reputation: 24524
To clip text with an ellipsis when it overflows a table cell, you will need to set the max-width
CSS property on each td
class for the overflow to work. No extra layout div
elements are required:
td
{
max-width: 100px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
For responsive layouts; use the max-width
CSS property to specify the effective minimum width of the column, or just use max-width: 0;
for unlimited flexibility. Also, the containing table will need a specific width, typically width: 100%;
, and the columns will typically have their width set as percentage of the total width
table {width: 100%;}
td
{
max-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
td.column_a {width: 30%;}
td.column_b {width: 70%;}
Historical: For IE 9 (or less) you need to have this in your HTML, to fix an IE-specific rendering issue
<!--[if IE]>
<style>
table {table-layout: fixed; width: 100px;}
</style>
<![endif]-->
Upvotes: 1205
Reputation: 12745
This worked in my case, in both Firefox and Chrome:
td {
max-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
width: 100%;
}
Upvotes: 8
Reputation: 116
I solved this using an absolutely positioned div inside the cell (relative).
td {
position: relative;
}
td > div {
position: absolute;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-width: 100%;
}
That's it. Then you can either add a top: value to the div or vertically center it:
td > div {
top: 0;
bottom: 0;
margin: auto 0;
height: 1.5em; // = line height
}
To get some space on the right side, you can reduce the max-width a little.
Upvotes: 7
Reputation: 5571
Wrap cell content in a flex block. As a bonus, cell auto fits visible width.
table {
width: 100%;
}
div.parent {
display: flex;
}
div.child {
flex: 1;
width: 1px;
overflow-x: hidden;
text-overflow: ellipsis;
}
<table>
<tr>
<td>
<div class="parent">
<div class="child">
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
</div>
<div>
</td>
</tr>
</table>
Upvotes: 11
Reputation: 3107
The solution below allows you to have table cell content that is long, but must not affect the width of the parent table, nor the height of the parent row. For example where you want to have a table with width:100%
that still applies auto-size feature to all other cells. Useful in data grids with "Notes" or "Comment" column or something.
Add these 3 rules to your CSS:
.text-overflow-dynamic-container {
position: relative;
max-width: 100%;
padding: 0 !important;
display: -webkit-flex;
display: -moz-flex;
display: flex;
vertical-align: text-bottom !important;
}
.text-overflow-dynamic-ellipsis {
position: absolute;
white-space: nowrap;
overflow-y: visible;
overflow-x: hidden;
text-overflow: ellipsis;
-ms-text-overflow: ellipsis;
-o-text-overflow: ellipsis;
max-width: 100%;
min-width: 0;
width:100%;
top: 0;
left: 0;
}
.text-overflow-dynamic-container:after,
.text-overflow-dynamic-ellipsis:after {
content: '-';
display: inline;
visibility: hidden;
width: 0;
}
Format HTML like this in any table cell you want dynamic text overflow:
<td>
<span class="text-overflow-dynamic-container">
<span class="text-overflow-dynamic-ellipsis" title="...your text again for usability...">
//...your long text here...
</span>
</span>
</td>
Additionally apply desired min-width
(or none at all) to the table cell.
Of course the fiddle: https://jsfiddle.net/9wycg99v/23/
Upvotes: 41
Reputation: 1758
Without using max-width
, or percentage column widths, or table-layout: fixed
etc.
https://jsfiddle.net/tturadqq/
How it works:
Step 1: Just let the table auto-layout do its thing.
When there's one or more columns with a lot of text, it will shrink the other columns as much as possible, then wrap the text of the long columns:
Step 2: Wrap cell contents in a div, then set that div to max-height: 1.1em
(the extra 0.1em is for characters which render a bit below the text base, like the tail of 'g' and 'y')
Step 3: Set title
on the divs
This is good for accessibility, and is necessary for the little trick we'll use in a moment.
Step 4: Add a CSS ::after
on the div
This is the tricky bit. We set a CSS ::after
, with content: attr(title)
, then position that on top of the div and set text-overflow: ellipsis
. I've coloured it red here to make it clear.
(Note how the long column now has a tailing ellipsis)
Step 5: Set the colour of the div text to transparent
And we're done!
Upvotes: 36
Reputation: 78686
When it's in percentage table width, or you can't set fixed width on table cell. You can apply table-layout: fixed;
to make it work.
table {
table-layout: fixed;
width: 100%;
}
td {
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
border: 1px solid red;
}
<table>
<tr>
<td>Lorem ipsum and dim sum yeah yeah yeah. Lorem ipsum and dim sum yeah yeah yeah. Lorem ipsum and dim sum yeah yeah yeah. Lorem ipsum and dim sum yeah yeah yeah. Lorem ipsum and dim sum yeah yeah yeah.</td>
<td>Lorem ipsum and dim sum yeah yeah yeah. Lorem ipsum and dim sum yeah yeah yeah. Lorem ipsum and dim sum yeah yeah yeah. Lorem ipsum and dim sum yeah yeah yeah. Lorem ipsum and dim sum yeah yeah yeah.</td>
</tr>
</table>
Upvotes: 22
Reputation: 527
It seems that if you specify table-layout: fixed;
on the table
element, then your styles for td
should take effect. This will also affect how the cells are sized, though.
Sitepoint discusses the table-layout methods a little here: http://reference.sitepoint.com/css/tableformatting
Upvotes: 29
Reputation: 1
This is the version that works in IE 9.
<div style="display:table; table-layout: fixed; width:100%; " >
<div style="display:table-row;">
<div style="display:table-cell;">
<table style="width: 100%; table-layout: fixed;">
<div style="text-overflow:ellipsis;overflow:hidden;white-space:nowrap;">First row. Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.</div>
</table>
</div>
<div style="display:table-cell;">
Top right Cell.
</div>
</div>
<div style="display:table-row;">
<div style="display:table-cell;">
<table style="width: 100%; table-layout: fixed;">
<div style="text-overflow:ellipsis;overflow:hidden;white-space:nowrap;">Second row - Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.</div>
</table>
</div>
<div style="display:table-cell;">
Bottom right cell.
</div>
</div>
</div>
Upvotes: -8
Reputation: 63729
Why does this happen?
It seems this section on w3.org suggests that text-overflow applies only to block elements:
11.1. Overflow Ellipsis: the ‘text-overflow’ property
text-overflow clip | ellipsis | <string>
Initial: clip
APPLIES TO: BLOCK CONTAINERS <<<<
Inherited: no
Percentages: N/A
Media: visual
Computed value: as specified
The MDN says the same.
This jsfiddle has your code (with a few debug modifications), which works fine if it's applied to a div
instead of a td
. It also has the only workaround I could quickly think of, by wrapping the contents of the td
in a containing div
block. However, that looks like "ugly" markup to me, so I'm hoping someone else has a better solution. The code to test this looks like this:
td, div {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
border: 1px solid red;
width: 80px;
}
Works, but no tables anymore:
<div>Lorem ipsum and dim sum yeah yeah yeah. Lorem ipsum and dim sum yeah yeah yeah. Lorem ipsum and dim sum yeah yeah yeah. Lorem ipsum and dim sum yeah yeah yeah. Lorem ipsum and dim sum yeah yeah yeah.</div>
Works, but non-semantic markup required:
<table><tr><td><div>Lorem ipsum and dim sum yeah yeah yeah. Lorem ipsum and dim sum yeah yeah yeah. Lorem ipsum and dim sum yeah yeah yeah. Lorem ipsum and dim sum yeah yeah yeah. Lorem ipsum and dim sum yeah yeah yeah.</div></td></tr></table>
Upvotes: 47