Truncating long strings with CSS: feasible yet? - css

Is there any good way of truncating text with plain HTML and CSS, so that dynamic content can fit in a fixed-width-and-height layout?
I've been truncating server-side by logical width (i.e. a blindly-guessed number of characters), but since a 'w' is wider than an 'i' this tends to be suboptimal, and also requires me to re-guess (and keep tweaking) the number of characters for every fixed width. Ideally the truncation would happen in the browser, which knows the physical width of the rendered text.
I've found that IE has a text-overflow: ellipsis property that does exactly what I want, but I need this to be cross-browser. This property seems to be (somewhat?) standard but isn't supported by Firefox. I've found various workarounds based on overflow: hidden, but they either don't display an ellipsis (I want the user to know the content was truncated), or display it all the time (even if the content wasn't truncated).
Does anyone have a good way of fitting dynamic text in a fixed layout, or is server-side truncation by logical width as good as I'm going to get for now?

Update: text-overflow: ellipsis is now supported as of Firefox 7 (released September 27th 2011). Yay! My original answer follows as a historical record.
Justin Maxwell has cross browser CSS solution. It does come with the downside however of not allowing the text to be selected in Firefox. Check out his guest post on Matt Snider's blog for the full details on how this works.
Note this technique also prevents updating the content of the node in JavaScript using the innerHTML property in Firefox. See the end of this post for a workaround.
CSS
.ellipsis {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
-o-text-overflow: ellipsis;
-moz-binding: url('assets/xml/ellipsis.xml#ellipsis');
}
ellipsis.xml file contents
<?xml version="1.0"?>
<bindings
xmlns="http://www.mozilla.org/xbl"
xmlns:xbl="http://www.mozilla.org/xbl"
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
>
<binding id="ellipsis">
<content>
<xul:window>
<xul:description crop="end" xbl:inherits="value=xbl:text"><children/></xul:description>
</xul:window>
</content>
</binding>
</bindings>
Updating node content
To update the content of a node in a way that works in Firefox use the following:
var replaceEllipsis(node, content) {
node.innerHTML = content;
// use your favorite framework to detect the gecko browser
if (YAHOO.env.ua.gecko) {
var pnode = node.parentNode,
newNode = node.cloneNode(true);
pnode.replaceChild(newNode, node);
}
};
See Matt Snider's post for an explanation of how this works.

2014 March: Truncating long strings with CSS: a new answer with focus on browser support
Demo on http://jsbin.com/leyukama/1/ (I use jsbin because it supports old version of IE).
<style type="text/css">
span {
display: inline-block;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis; /** IE6+, Firefox 7+, Opera 11+, Chrome, Safari **/
-o-text-overflow: ellipsis; /** Opera 9 & 10 **/
width: 370px; /* note that this width will have to be smaller to see the effect */
}
</style>
<span>Some very long text that should be cut off at some point coz it's a bit too long and the text overflow ellipsis feature is used</span>
The -ms-text-overflow CSS property is not necessary: it is a synonym of the text-overflow CSS property, but versions of IE from 6 to 11 already support the text-overflow CSS property.
Successfully tested (on Browserstack.com) on Windows OS, for web browsers:
IE6 to IE11
Opera 10.6, Opera 11.1, Opera 15.0, Opera 20.0
Chrome 14, Chrome 20, Chrome 25
Safari 4.0, Safari 5.0, Safari 5.1
Firefox 7.0, Firefox 15
Firefox: as pointed out by Simon Lieschke (in another answer), Firefox only support the text-overflow CSS property from Firefox 7 onwards (released September 27th 2011).
I double checked this behavior on Firefox 3.0 & Firefox 6.0 (text-overflow is not supported).
Some further testing on a Mac OS web browsers would be needed.
Note: you may want to show a tooltip on mouse hover when an ellipsis is applied, this can be done via javascript, see this questions: HTML text-overflow ellipsis detection and HTML - how can I show tooltip ONLY when ellipsis is activated
Resources:
https://developer.mozilla.org/en-US/docs/Web/CSS/text-overflow#Browser_compatibility
http://css-tricks.com/snippets/css/truncate-string-with-ellipsis/
https://stackoverflow.com/a/1101702/759452
http://www.browsersupport.net/CSS/text-overflow
http://caniuse.com/text-overflow
http://msdn.microsoft.com/en-us/library/ie/ms531174(v=vs.85).aspx
http://hacks.mozilla.org/2011/09/whats-new-for-web-developers-in-firefox-7/

If you're OK with a JavaScript solution, there's a jQuery plug-in to do this in a cross-browser fashion - see http://azgtech.wordpress.com/2009/07/26/text-overflow-ellipsis-for-firefox-via-jquery/

OK, Firefox 7 implemented text-overflow: ellipsis as well as text-overflow: "string". Final release is planned for 2011-09-27.

Another solution to the problem could be the following set of CSS rules:
.ellipsis{
white-space:nowrap;
overflow:hidden;
}
.ellipsis:after{
content:'...';
}
The only drawback with the above CSS is that it would add the "..." irrespective of whether the text-overflows the container or not. Still, if you have a case where you have a bunch of elements and are sure that content will overflow, this one would be a simpler set of rules.
My two cents. Hats off to the original technique by Justin Maxwell

As of 2022, there is a new approach to that task, this is CSS rule line-clamp, which basically tells how many lines should be kept and all the rest will be trimmed. Below is an example, where you can drag the corner and experiment with dimensions of the div.
#resizable {
width: 400px;
height: 150px;
padding: 0 20px;
}
.wrapper {
border: 1px solid #dddddd;
background: #ffffff;
color: #333333;
position: relative;
}
.slider-text-wrapper p, .slider-text-wrapper .h1 {
width: 100%;
word-break: break-all;
display: -webkit-box;
-webkit-box-orient: vertical;
-moz-box-orient: vertical;
-ms-box-orient: vertical;
box-orient: vertical;
-webkit-line-clamp: 4;
-moz-line-clamp: 4;
-ms-line-clamp: 4;
line-clamp: 4;
overflow: hidden;
}
.slider-text-wrapper .h1 {
-webkit-line-clamp: 2;
-moz-line-clamp: 2;
-ms-line-clamp: 2;
line-clamp: 2;
font-size: 20px;
margin: 10px 0;
}
<link rel="stylesheet" href="https://code.jquery.com/ui/1.13.1/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/jquery-3.6.0.js"></script>
<script src="https://code.jquery.com/ui/1.13.1/jquery-ui.js"></script>
<script>
$( function() {
$( "#resizable" ).resizable();
} );
</script>
<div id="resizable" class="ui-widget-content wrapper">
<div class="slider-text-wrapper">
<p class="h1">Example headline with surplus of words without any meaning, for just mere demonstration of html and css</p>
<p class="slider-text-intro">Some representative placeholder content for the first slide of the carousel. Some representative placeholder content for the first slide of the carousel. Some representative placeholder content for the first slide of the carousel. Some representative placeholder content for the first slide of the carousel.</p>
</p>
</div>

Related

FF3.0.7 Text wrap

Clutching at straws here but anyone got a solution for wrapping text in Firefox 3.0.7?
Text should wrap within container like other browsers.
Example: http://jsfiddle.net/4t7Ut/ (obviously viewed in FF3.0.7)
#container {
border: 1px dashed;
width: 100px;
}
.text-to-wrap {
white-space: pre-wrap; /* css-3 */
white-space: -moz-pre-wrap; /* Mozilla, since 1999 */
white-space: -pre-wrap; /* Opera 4-6 */
white-space: -o-pre-wrap; /* Opera 7 */
word-wrap: break-word; /* Internet Explorer 5.5+ */
}
...
<div id="container">
<div class="text-to-wrap ">VWvU3dpVq5wJio6oFE82pmQuBTRzbii4dLd4NGBr332V2P4Skx8GwLozZrczNoRPmqWSrxnLEKh5PBZ6s3AjMFX3ftLHyuR7RGSA</div>
</div>
To make the content wrap so that it is divided into lines with each line containing as many characters as possible (except for the last line of course), you would need to add the <wbr> tag after each character in the text content, in order to make things work that way even on an ancient browser like Firefox 3. You could use client-side scripting for the purpose:
<script>
var cont = document.getElementById('container').getElementsByTagName('div')[0];
cont.innerHTML = cont.innerHTML.replace(/(.)/g, '$1<wbr>');
alert(cont.innerHTML);
</script>
It almost never adequate to allow such breaking. Both human and computer languages have their own line breaking rules. So the <wbr> tag should be inserted at suitable positions only, either manually or using an algorithm suitable for the content.
Instead of <wbr>, you could also use its character-level counterpart ZERO WIDTH SPACE (​). It is not supported by very old browsers, though Firefox 3 seems to be OK with it.
try it:
use width:100%; display:inline-block; to .text-to-wrap

How do I wrap text with no whitespace inside a <td>?

I've used:
word-break:break-all;
table-layout:fixed;
and the text wraps in Chrome but not Firefox.
Update: I decided to change the design so it didn't need the wrap; trying to sort out a CSS fix/hack was proving too frustrating and time consuming.
Try this, I think this will work for something like "AAAAAAAAAAAAAAAAAAAAAARRRRRRRRRRRRRRRRRRRRRRGGGGGGGGGGGGGGGGGGGGG"
will produce
AARRRRRRRRRRRRRRRRRRRR
RRGGGGGGGGGGGGGGGGGGGG
G
I have taken my example from a couple different websites on Google. I have tested this on ff 5.0, IE 8.0, and Chrome 10.
.wrapword {
white-space: -moz-pre-wrap !important; /* Mozilla, since 1999 */
white-space: -webkit-pre-wrap; /* Chrome & Safari */
white-space: -pre-wrap; /* Opera 4-6 */
white-space: -o-pre-wrap; /* Opera 7 */
white-space: pre-wrap; /* CSS3 */
word-wrap: break-word; /* Internet Explorer 5.5+ */
word-break: break-all;
white-space: normal;
}
<table style="table-layout:fixed; width:400px">
<tr>
<td class="wrapword">
</td>
</tr>
</table>
Here is advanced version of what OP asked.
Sometimes, what happens is that, our client wants us to give '-' after word break to end of line.
Like
AAAAAAAAAAAAAAAAAAAAAAABBBBBBBBBBB
break to
AAAAAAAAAAAAAAAAAAAAAAA-
BBBBBBBBB
So, there is new CSS property if supported, usually supported in latest browsers.
.dont-break-out {
/* These are technically the same, but use both */
overflow-wrap: break-word;
word-wrap: break-word;
-ms-word-break: break-all;
/* This is the dangerous one in WebKit, as it breaks things wherever */
word-break: break-all;
/* Instead use this non-standard one: */
word-break: break-word;
/* Adds a hyphen where the word breaks, if supported (No Blink) */
-ms-hyphens: auto;
-moz-hyphens: auto;
-webkit-hyphens: auto;
hyphens: auto;
}
I am using this one.
I hope somebody will have demand like this.
For an automatic table layout try to style the concerned td combining the attributes max-width and word-wrap.
Eg: <td style="max-width:175px; word-wrap:break-word;"> ... </td>
Tested in Firefox 32, Chrome 37 and IE11.
You can manually inject zero width spaces (​) to create break points.
Set a column width for the td tag.
What worked for me was:
.output {
overflow-wrap: break-word;
word-wrap: break-word;
word-break: break-word;
}
I think this is a long standing issue in Firefox, that harks back to Mozilla and Netscape. I'll bet you were having the issue with the display of long URLs. I think it is an issue with the rendering engine rather than something you can fix with CSS, without some ugly hacks.
Makes sense to change the design.
This looked hopeful though: http://hacks.mozilla.org/2009/06/word-wrap/
I'm using Angular for my project, and managed to solve this with a simple filter:
Template:
<td>{{string | wordBreak}}</td>
Filter:
app.filter('wordBreak', function() {
return function(string) {
return string.replace(/(.{1})/g, '$1​');
}
})
You can't see it, but after $1 there is an invisible space (thanks #kingjeffrey for the tip), which enabled word breaks for table cells.
One slightly hackish way of doing this is by processing the text to add space between each letter. Replace spaces with Then use the letter-spacing css attribute to bring the spaces down.
I know, it's a hack... but if NOTHING else works, it should wrap without problem.

Why is Chrome ignoring my CSS selector?

In the following page http://ada.kiexpro.com/test2/map.html
I added:
white-space: normal;
to wrap the copyright text that is coming our from the Google map API.
It works in FF and IE but Chrome seems to ignore the CSS selector:
global.css:
#cm_map span {
white-space: normal !important;
}
Google has an anonymous div with inline styles surrounding the copyright content. Only hook I can see is that it's a sibling of the "logocontrol" div. To override, try something like the following:
#cm_map #logocontrol + div[style] {
left: auto !important;
line-height: 13px;
right: 5px;
bottom: 6px !important;
white-space: normal;
width: 95%;
}
Not thoroughly tested but something like this should work.
This may also be a bug in Chrome: white-space normal !important doesn't override nowrap.
I've reported this bug at http://code.google.com/p/chromium/issues/detail?id=89573, but based on how they have been completely ignoring a more important issue since 2009, I have little hope of this being fixed.
Here is another example of chrome ignoring the important. This time its on the position. Unclicking the "position: relative" does bring the absolute into the picture. So the style is valid.

CSS line break in TD

If I have a very long string (without spaces!). Can I force the browser to line break it, for example, in a table's td via CSS. Width does not seem to have any effect.
Note: I know it is very unlikely for someone to submit a long string without spaces but you never know ...
I tried:
.gridrow td
{
padding: 1em;
text-align: center;
word-wrap: break-word;
}
and I use FF as my browser. word-wrap only seems to be used in CSS3?
I think what you mean is in CSS:
#id
{
max-width: 100px; /*or whatever*/
word-wrap: break-word;
}
Tested on your site with Firebug, it works.
Reference article.
Tables are a special case. They'll keep on expanding if they can, so as not to obscure any content; you can't use overflow: hidden on them either. Here are some options:
Use an optional breaking character. (Source: http://www.quirksmode.org/oddsandends/wbr.html ) If you can control insert a character like ­ or <wbr> programatically into long strings, this may be a solution.
Perhaps preferably, depending on your situation, you can limit the table to use strict widths, at which point it should obey your rule:
table {
table-layout: fixed;
width: 100%;
}
table td {
word-wrap: break-word; /* All browsers since IE 5.5+ */
overflow-wrap: break-word; /* Renamed property in CSS3 draft spec */
}
i think there wordwrap element. search for the wordwrap.
word-wrap: break word
EDITED
REF Word-wrap in a html table
it suggest that there's no good way of doing this.

Is there a way to word-wrap long words in a div?

I know Internet Explorer has a word-wrap style, but I'd like to know if there is a cross-browser method of doing so to text in a div.
Preferably CSS but JavaScript snippets would work ok too.
I'm referring to long strings.
Reading the original comment, rutherford is looking for a cross-browser way to wrap unbroken text (inferred by his use of word-wrap for IE, designed to break unbroken strings).
/* Source: http://snipplr.com/view/10979/css-cross-browser-word-wrap */
.wordwrap {
white-space: pre-wrap; /* CSS3 */
white-space: -moz-pre-wrap; /* Firefox */
white-space: -pre-wrap; /* Opera <7 */
white-space: -o-pre-wrap; /* Opera 7 */
word-wrap: break-word; /* IE */
}
I've used this class for a bit now, and works like a charm. (note: I've only tested in FireFox and IE)
Most of the previous answer didn't work for me in Firefox 38.0.5. This did...
<div style='padding: 3px; width: 130px; word-break: break-all; word-wrap: break-word;'>
// Content goes here
</div>
Documentation:
word-break
word-wrap
white-space: pre-wrap
quirksmode.org/css/whitespace.html
Aaron Bennet's solution is working perfectly for me, but i had to remove this line from his code --> white-space: -pre-wrap; beacause it was giving an error, so the final working code is the following:
.wordwrap {
white-space: pre-wrap; /* CSS3 */
white-space: -moz-pre-wrap; /* Firefox */
white-space: -o-pre-wrap; /* Opera 7 */
word-wrap: break-word; /* IE */
}
thank you very much
As david mentions, DIVs do wrap words by default.
If you are referring to really long strings of text without spaces, what I do is process the string server-side and insert empty spans:
thisIsAreallyLongStringThatIWantTo<span></span>BreakToFitInsideAGivenSpace
It's not exact as there are issues with font-sizing and such. The span option works if the container is variable in size. If it's a fixed width container, you could just go ahead and insert line breaks.
You can try specifying a width for the div, whether it be in pixels, percentages or ems, and at that point the div will remain that width and the text will wrap automatically then within the div.

Resources