This may be a bit late in the game, but I was looking to find a solution to this, and a colleague suggested a very elegant one, which I'll share. It requires some JS, but not a lot.
Imagine you have a div
of a size you need to put your label into:
<div style="width: 200px; overflow: hidden"></div>
Now, you have a function which will take two params: a string with the label, and a DOM element (this div
) to fit it into:
function setEllipsisLabel(div, label)
The first thing you do is create a span
with this label, and put it into the div
:
var span = document.createElement('span');
span.appendChild(document.createTextNode(label));
span.style.textOverflow = 'ellipsis';
span.style.display = 'inline-block';
div.appendChild(span);
We set the text-overflow
property to "ellipsis" so that as the text gets chopped off, a nice "..." is added at the end to illustrate this. We also set display
to be "inline-block" so that these elements have real pixel dimensions we can manipulate later. So far, nothing we could not have done with pure CSS.
But we want the ellipsis in the middle. First, we should find out if we need it at all... This can be done by comparing div.clientWidth
to span.clientWidth
- ellipsis is only needed if the span
is wider than the div
.
If we do need an ellipsis, let's start by saying that we want a fixed number of characters shown at the end of the word - say 10. So let's create a span containing only the last 10 characters of the label, and stick it into the div:
var endSpan = document.createElement('span');
endSpan.style.display = 'inline-block';
endspan.appendChild(document.createTextNode(label.substring(label.length - 10)));
div.appendChild(endSpan);
Now, let's override the width of the original span
to accommodate the new one:
span.style.width = (div.clientWidth - endSpan.clientWidth) + 'px';
As a result of this, we now have a DOM structure that looks something like this:
<div style="width: 200px; overflow: hidden">
<span style="display: inline-block; text-overflow: ellipsis; width: 100px">
A really long label is shown in this span
</span>
<span style="display: inline-block"> this span</span>
</div>
Because the first span
has text-overflow
set to "ellipsis", it will show "..." at the end, followed by the 10 characters of the second span, resulting in the ellipsis showing approximately in the middle of the div
.
You don't need to hardcode the 10 character length for the endSpan either: this can be approximated by calculating ratio of the span
's initial width to that of the div
, subtracting the appropriate proportion from the length of the label and dividing by two.