A: 

The CSS property text-overflow:ellipsis does this. But I think its a CSS3 property. However someone has made it work here

naikus
Unfortunately, it works only for single line text
Edward
@Edward, looks like its real tough or may be not possible
naikus
A: 

not sure if this is what you're looking for, it uses min-height instead of height.

    <div id="content" style="min-height:10px;width:190px;background:lightblue;">
    <?php 
        function truncate($text,$numb) {
            // source: www.kigoobe.com, please keep this if you are using the function
            $text = html_entity_decode($text, ENT_QUOTES);
            if (strlen($text) > $numb) {
                $text = substr($text, 0, $numb);
                $etc = "..."; 
                $text = $text.$etc;
            } 
            $text = htmlentities($text, ENT_QUOTES);
            return $text;
        }
        echo truncate("this is a multi-lines text block, some lines inside the div, while some outside", 63);
    ?>
    </div>
khairil
The problem is the number 63 in your codes, if the number is known then everything become easy, just a truncate function does this job, as your codes. However, how to know the number? In other words, how to know where the text will be line-breaked? If this question can be answered, then the problem can be simply resolved in logic of "1, calculate the number; 2, truncate"
Edward
A: 

You probably can't do it (currently?) without a fixed-width font like Courier. With a fixed-width font every letter occupies the same horizontal space, so you could probably count the letters and multiply the result with the current font size in ems or exs. Then you would just have to test how many letters fit on one line, and then break it up.

Alternatively, for non-fixed-with fonts you might be able to create a mapping for all possible characters (like i = 2px, m = 5px) and then do the math. A lot of ugly work though.

DanMan
A: 

To expand on @DanMan's solution: in the case where variable-width fonts are used, you could use an average font width. This has two problems: 1) a text with too many W's would overflow and 2) a text with too many I's would be truncated earlier.

Or you could take a worst-case approach and use the width of the letter "W" (which I believe is the widest). This removes problem 1 above but intensifies problem 2.

A different approach could be: leave overflow: clip in the div and add an ellipsis section (maybe another div or image) with float: right; position: relative; bottom: 0px; (untested). The trick is to make the image appear above the end of text.

You could also only display the image when you know it's going to overflow (say, after about 100 characters)

st.never
+1  A: 

Just a quick basic idea.

I was testing with the following markup:

<div id="fos">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin nisi ligula, dapibus a volutpat sit amet, mattis et dui. Nunc porttitor accumsan orci id luctus. Phasellus ipsum metus, tincidunt non rhoncus id, dictum a lectus. Nam sed ipsum a lacus sodales eleifend. Vestibulum lorem felis, rhoncus elementum vestibulum eget, dictum ut velit. Nullam venenatis, elit in suscipit imperdiet, orci purus posuere mauris, quis adipiscing ipsum urna ac quam.</p>  
</div>

And CSS:

#fos { width: 300px; height: 190px; overflow: hidden; }
#fos p { padding: 10px; margin: 0; }

Applying this jQuery will accomplish the desired result:

var p=$('#fos p');
var divh=$('#fos').height();
while ($(p).outerHeight()>divh) {
    $(p).text(function (index, text) {
        return text.replace(/\W*\s(\S)*$/, '...');
    });
}

It repeatedly tries to remove the last word of the text until it reaches the desired size. Because of the overflow: hidden; the process remains invisible and even with JS turned off the result remains 'visually correct' (without the "..." of course).

If you combine this with a sensible truncation on the server-side (that leaves only a small overhead) then it will run quicker :).

Again, this is not a complete solution, just an idea.

bazmegakapa