With CSS, use "..." for overflowed block of multi-lines

with

overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;

"..." will be shown in the end of the line if overflowed. However, this will be shown only in one line. But I would like it to be shown in multi-lines.

It may looks like:

+--------------------+
|abcde feg hij   dkjd|
|dsji jdia js ajid  s|
|jdis ajid dheu d ...|/*Here it's overflowed, so "..." is shown. */
+--------------------+

There are also several jquery plugins that deal with this issue, but many do not handle multiple lines of text. Following works:

  • http://pvdspek.github.com/jquery.autoellipsis/
  • http://dotdotdot.frebsite.nl/
  • http://keith-wood.name/more.html
  • http://github.com/tbasse/jquery-truncate

There also some preformance tests.


I have hacked around until I've managed to achieve something close to this. It comes with a few caveats:

  1. It's not pure CSS; you have to add a few HTML elements. There's however no JavaScript required.
  2. The ellipsis is right-aligned on the last line. This means that if your text isn't right-aligned or justified, there may be a noticable gap between the last visible word and the ellipsis (depending on the length of the first hidden word).
  3. The space for the ellipsis is always reserved. This means that if the text fits in the box almost precisely, it may be unnecessarily truncated (the last word is hidden, although it technically wouldn't have to).
  4. Your text needs to have a fixed background color, since we're using colored rectangles to hide the ellipsis in cases where it's not needed.

I should also note that the text will be broken at a word boundary, not a character boundary. This was deliberate (since I consider that better for longer texts), but because it's different from what text-overflow: ellipsis does, I thought I should mention it.

If you can live with these caveats, the HTML looks like this:

<div class="ellipsify">
    <div class="pre-dots"></div>
    <div class="dots">&hellip;</div>
    <!-- your text here -->
    <span class="hidedots1"></span>
    <div class="hidedots2"></div>
</div>

And this is the corresponding CSS, using the example of a 150 pixel wide box with three lines of text on a white background. It assumes you have a CSS reset or similar that sets margins and paddings to zero where necessary.

/* the wrapper */
.ellipsify {
    font-size:12px;
    line-height:18px;
    height: 54px;       /* 3x line height */
    width: 150px;
    overflow: hidden;
    position: relative; /* so we're a positioning parent for the dot hiders */
    background: white;
}

/* Used to push down .dots. Can't use absolute positioning, since that
   would stop the floating. Can't use relative positioning, since that
   would cause floating in the wrong (namely: original) place. Can't 
   change height of #dots, since it would have the full width, and
   thus cause early wrapping on all lines. */
.pre-dots {
    float: right;
    height: 36px;  /* 2x line height (one less than visible lines) */
}

.dots {
    float: right; /* to make the text wrap around the dots */
    clear: right; /* to push us below (not next to) .pre-dots */
}

/* hides the dots if the text has *exactly* 3 lines */
.hidedots1 {
    background: white;
    width: 150px;
    height: 18px;       /* line height */
    position: absolute; /* otherwise, because of the width, it'll be wrapped */
}

/* hides the dots if the text has *less than* 3 lines */
.hidedots2 {
    background: white; 
    width: 150px;
    height: 54px;       /* 3x line height, to ensure hiding even if empty */
    position: absolute; /* ensures we're above the dots */
}

The result looks like this:

image of the rendered result with different text lengths

To clarify how it works, here's the same image, except that .hidedots1 is hightlighted in red, and .hidedots2 in cyan. These are the rectangles that hide the ellipsis when there's no invisible text:

the same image as above, except that the helper elements are highlighted in color

Tested in IE9, IE8 (emulated), Chrome, Firefox, Safari, and Opera. Does not work in IE7.