Today I needed to put one line of possibly long text into table. So text may be wider than table cell. In that case client needs to see end of that text because it contains more important data. What is worse my cell width depends on client resolution so I cannot trim text on server. Here is simple illustration:
There is CSS text-overflow property that can end text that can visualize by ellipsis (“…”) that text is longer than element size so it overflows element and is hidden. That is fine for text has more important part on the beginning. But what about text that has more important part on the end? It would be better to show ellipsis on left side, right?
Unfortunately it is not possible nowadays, there is only outdated draft of such function done by W3C. It would allow you to define behavior for both sides of text.
Other possibility are various CSS hacks, like this one, or this one, or … They are based on nasty tricks and suffer for many problems. One is common to all of them - they are using clipping by rectangle so text which is on border is clipped too. For example it cuts letter O so it looks like bracket. That is confusing, so this way was not feasible for me. See first example on image above.
So there is only one option. Yes, JavaScript :-/ My sample is using JQuery and works like this:
Here is the code (download from github):
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Left text-overflow test page</title>
<script src="https://code.jquery.com/jquery-1.12.0.min.js"></script>
<script>
//on document ready
$(document).ready(function() { shortenTexts(); });
//on widow resize
$(window).resize(function() { shortenTextsDelayed(); });
//wait for rendering done
function shortenTextsDelayed() { window.setTimeout(shortenTexts, 100); }
function shortenTexts() {
//get ruler
var measureBox = $("#ruler");
var measureBoxSpan = measureBox.children("span").first();
//iterate over texts that should be shortened
$("div.shorten").each(function(index, element){
//target span
var span = $(element).children("span").first();
//full text var
text = $(element).data("original");
//init by full text
measureBoxSpan.text(text);
//while span in ruler is bigger than ruler
while (text.length>0 && measureBoxSpan.width()>measureBox.width()) {
//shorten string
text = text.substring(1);
//set new text measureBoxSpan.text("…"+text);
}
//set target text by succeeded text
span.text(measureBoxSpan.text());
});
}
</script>
<style>
body {
padding: 0px;
margin: 0px;
}
body > div {
max-width: 90%;
font-size: 25px;
overflow: hidden;
white-space: nowrap;
border: 1px solid gray;
padding: 5px;
}
div.ellipsis {
text-overflow: ellipsis;
}
#ruler {
position: absolute;
visibility: hidden;
}
</style>
</head>
<body>
<h1>Implicit</h1>
<div>
<span> This is sooo long text. Probably it will overflow, right? But maybe, maybe there will be extremely important information that you should not miss in the end. Information that you should not miss. The ultimate answer. Curious? Now I will count 1 2 3 4 5 6 7 8 9. Really? I do not believe you! REALLY! So the ultimate answer is: 42! </span>
</div>
<h1>text-overflow: ellipsis</h1>
<div class="ellipsis">
<span> This is sooo long text. Probably it will overflow, right? But maybe, maybe there will be extremely important information that you should not miss in the end. Information that you should not miss. The ultimate answer. Curious? Now I will count 1 2 3 4 5 6 7 8 9. Really? I do not believe you! REALLY! So the ultimate answer is: 42! </span>
</div>
<h1>JavaScript shortening from left</h1>
<div id="ruler">
<span> </span>
</div>
<div class="shorten" data-original="This is sooo long text. Probably it will overflow, right? But maybe, maybe there will be extremely important information that you should not miss in the end. Information that you should not miss. The ultimate answer. Curious? Now I will count 1 2 3 4 5 6 7 8 9. Really? I do not believe you! REALLY! So the ultimate answer is: 42!">
<span> </span>
</div>
</body>
</html>
Result looks like, try to play with browser window size - overflow should adapt:
Enjoy!