213

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?

Community
  • 1
  • 1
Sam Stokes
  • 14,617
  • 7
  • 36
  • 33
  • related: [Applying Ellipsis to Multiline Text](http://stackoverflow.com/q/33058004/3597276) – Michael Benjamin Oct 24 '15 at 13:19
  • 1
    Possible duplicate of [Insert ellipsis (...) into HTML tag if content too wide](http://stackoverflow.com/questions/536814/insert-ellipsis-into-html-tag-if-content-too-wide) – Naeem Shaikh Feb 15 '16 at 13:34

6 Answers6

189

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.

Simon Lieschke
  • 13,058
  • 6
  • 46
  • 60
  • That's awesome, thanks for pointing it out! The unselectable text and restrictions on what content can go in the truncated div are a shame, but generally that looks like a good solution. – Sam Stokes Jul 09 '09 at 17:15
  • Only real frustration I've hit is that spaces are rendered as  , so indentation isn't really feasible... =/ – Matchu Aug 11 '09 at 03:36
  • I ran across this same problem too. I can't believe Firefox doesn't support this in some form yet. – mcjabberz Aug 24 '09 at 18:42
  • does this approach work for anyone on OPTION elements of SELECT controls on Webkit and IE8. Webkit doesnt seem to be doing anything for me and IE8 just clips it without the ellipsis. – Rajat Apr 09 '10 at 22:58
  • Microsoft's documentation for `text-overflow` doesn't indicate support for `option` elements (see the **Applies To** section at http://msdn.microsoft.com/en-us/library/ms531174(VS.85).aspx). – Simon Lieschke Apr 10 '10 at 02:08
  • Just a heads up that the XUL hack currently doesn't work in Firefox 4.0 (which is in development as of writing). I'll keep people updated. https://bugzilla.mozilla.org/show_bug.cgi?id=312156#c94 – Simon Lieschke Sep 21 '10 at 22:40
  • The [ETA for Firefox support for this](https://bugzilla.mozilla.org/show_bug.cgi?id=312156#c124) (as of writing) is Firefox 6. – Simon Lieschke Apr 13 '11 at 03:23
  • Works great! I didn't implement the Firefox stuff for my project since it was annoying. Screw the Firefox users :) – Sam Soffes May 11 '11 at 05:21
  • [`text-overflow: ellipsis` is now supported](http://hacks.mozilla.org/2011/09/whats-new-for-web-developers-in-firefox-7/) as of Firefox 7. Yay! – Simon Lieschke Sep 28 '11 at 07:27
  • Doesn't work for table cells I noticed. You need to wrap the content inside a DIV and apply the style to the DIV, not the table cell (in Chrome/Webkit at least). – Simon East Feb 04 '12 at 23:45
  • @Simon also see [this answer](http://stackoverflow.com/questions/1554928/how-to-hide-table-row-overflow). – Simon Lieschke Feb 06 '12 at 20:17
46

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:

Community
  • 1
  • 1
Adriano
  • 19,463
  • 19
  • 103
  • 140
19

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/

akokskis
  • 1,486
  • 15
  • 32
RichieHindle
  • 272,464
  • 47
  • 358
  • 399
  • That's definitely useful, thanks! Seems like all the browsers except Firefox support the CSS property, so with this plugin, the only people it wouldn't work for are Firefox users who've disabled Javascript - and it's a graceful degradation anyway. Any idea what the performance implications are like? – Sam Stokes Apr 29 '09 at 14:39
  • No, sorry... I haven't used the code in real life, just played with the demo. It would be easy to take the demo and cut-and-paste it a hundred times into the same page. – RichieHindle Apr 29 '09 at 14:42
  • 2
    JavaScript truncate() (be it dot-string for jQuery or Prototype or whatever) are only a half-way solution, because they do not take into account the character width. So, if you want to truncate text because of a pre-defined limited space, those functions only work reliably when using monospaced fonts. Any serious solution would have to operate on glyphs, not on character count. – mxk Aug 26 '09 at 08:32
  • @Matthias: Perhaps the code has been updated since you tested it, but I've just looked at the demo and it works perfectly with a variable-width font. – RichieHindle Jul 29 '10 at 13:31
7

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

j.j.
  • 71
  • 1
  • 1
6

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

Rajat
  • 32,970
  • 17
  • 67
  • 87
  • The problem with pseudo code is that "..." still gets cut off or hidden if text does overflow. I was hoping that if text overflows, it would make sure "..." to be shown. Clearly, that's not the case :( – Antony Mar 22 '12 at 14:51
  • @Antony Just position the pseudo element: `position: absolute; right: 0;` (and don't forget `position: relative` on the real element for it to work). It will overlap with the text though so you might want to add a background color too. – last-child Jun 17 '13 at 11:45
0

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>
Yarik
  • 742
  • 8
  • 13