Truncating long strings with CSS: feasible yet?

Sam Stokes picture Sam Stokes · Apr 29, 2009 · Viewed 139.3k times · Source

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?

Answer

Simon Lieschke picture Simon Lieschke · Jul 9, 2009

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.