Reputation: 5731
I'm trying to achieve a responsive table width text-overflow: ellipsis;
in the middle cell that looks like this:
| Button 1 | A one-lined text that is too long and has to be... | Button 2 |
The whole table should have width: 100%;
to be as large as the device. I can't set a fixed width on Button 1
nor Button 2
since the application is multilingual (a max-width
should be possible though).
I can try whatever I want, the ...
only appears when I set a fixed width. How can I tell the middle cell to "use the space available" without the help of JavaScript?
Upvotes: 41
Views: 32630
Reputation: 542
I originally used https://stackoverflow.com/a/19623352/2453676, but I had a use case where I didn't want to use a table. The same thing can be done using only divs.
<div class="ellipsis-div__parent" title="text that will be truncated with ellipsis">
<div class="ellipsis-div__child">
text that will be truncated with ellipsis
</div>
</div>
./ellipsis-div.css
.ellipsis-div__parent {
display: table;
table-layout: fixed;
width: 100%;
}
.ellipsis-div__child {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
Here is a working example. https://codepen.io/54rktech/pen/ZErgYYY
Upvotes: 0
Reputation: 70139
This is not really a clean solution, but it uses no JS and works in every browser I've tested.
My solution consists in wrapping the cell's contents inside a table with table-layout: fixed
and width: 100%
.
See the demo.
Here's the full solution:
<table class="main-table">
<tr>
<td class="nowrap">Button 1</td>
<td>
<table class="fixed-table">
<tr>
<td>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Delectus doloremque magni illo reprehenderit consequuntur quia dicta labore veniam distinctio quod iure vitae porro nesciunt. Minus ipsam facilis! Velit sapiente numquam.</td>
</tr>
</table>
</td>
<td class="nowrap">Button 2</td>
</tr>
</table>
.main-table {
width: 100%;
}
.fixed-table {
/* magic */
width: 100%;
table-layout: fixed;
/*not really necessary, removes extra white space */
border-collapse: collapse;
border-spacing: 0;
border: 0;
}
.fixed-table td {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.nowrap {
/* used to keep buttons' text in a single line,
* remove this class to allow natural line-breaking.
*/
white-space: nowrap;
}
It's not really clear what's the intent for the side buttons, hence I've used white-space: nowrap
to keep them in the same line. Depending on the use case, you may prefer to apply a min-width
and let them line-break naturally.
Upvotes: 82
Reputation: 13013
<div class="container">
<div>
Button 1
</div>
<div class="fill">
<div class="lockText">
A one-lined text that is too long and has to be...
</div>
</div>
<div>
Button 2
</div>
</div>
The trick is to set up a table layout with a cell that takes up leftover space first (css tables, mind you!).
.container {
display: table;
width: 100%;
}
.container > div {
display: table-cell;
white-space: nowrap;
position : relative;
width : auto;
/*make it easier to see what's going on*/
padding : 2px;
border : 1px solid gray;
}
.container > .fill {
width : 100%;
}
Then add your text that constrains itself within.
.lockText {
position : absolute;
left : 0;
right : 0;
overflow: hidden;
text-overflow: ellipsis;
}
Upvotes: 1
Reputation: 177
HTML
<tr>
<td>
<span class="ellipsis"> A very looooooooooooooooooooooooooooooong string</span>
</td>
</tr>
CSS
td {
position: relative;
}
.ellipsis {
/*Here is the trick:*/
position: absolute;
width: 100%;
/*End of the trick*/
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}
Upvotes: 10
Reputation: 31
After banging my head for hours, with no solution that worked, finally found it.
The element you want for the base of the overflow nees a min/max width, where the max is inferior to the min width. You can then overflow the lement or a child of it, where you can set the with whatever way you choose: %, px, auto.
I tried it in more than one tricky situation and it works on all.
I'll try to post a fiidle with my examples but this should help you going.
/* Apply on base element for proper overflow */
max-width: 1px;
min-width: 10000px;
/* Apply on self or child, according to need */
width: 100%;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
Upvotes: 3
Reputation: 49
A cleaner way would be to simply set a max-width on the td.
Based on @Fabrício Matté's reply,
<table class="main-table">
<tr>
<td class="nowrap">Button 1</td>
<td class="truncate">
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Delectus doloremque magni illo reprehenderit consequuntur quia dicta labore veniam distinctio quod iure vitae porro nesciunt. Minus ipsam facilis! Velit sapiente numquam.</td>
<td class="nowrap">Button 2</td>
</tr>
And
body { margin: 0; }
.main-table {
width: 100%;
}
.truncate {
text-overflow: ellipsis;
white-space : nowrap;
overflow : hidden;
max-width : 100px; /* Can be any size, just small enough */
}
.nowrap {
white-space: nowrap;
}
I have no idea why this works, but it does, so if someone can figure how why applying a max-width works then please let me know as I did it by accident.
Upvotes: 4
Reputation: 25081
Set your 100% width on the table and specify a fixed
table-layout:
table {
width: 100%;
table-layout: fixed;
}
Then, set the following for whichever table cell should have the ellipsis:
td:nth-child(2) {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
Voila! Responsive table with an ellipsis overflow!
Demo: http://jsfiddle.net/VyxES/
Upvotes: 19
Reputation: 4909
[update] My apologies, does not seem to work 'just like that': http://jsfiddle.net/kQKfc/1/
Will leave it here though, because it certain situations it does the trick for us.
[/update]
We have this css in our project, give it a shot:
.nowr
{
display: block;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
Upvotes: -1