Is it possible to use text-overflow:ellipsis on multiline text?
HtmlCssHtml Problem Overview
I have a <p>
tag with a specific width and height.
I want to use text-overflow:ellipsis
to get ...
if the text in the tag is too long.
Is this possible to solve with css on multiline text?
Html Solutions
Solution 1 - Html
Googling doesn't reveal anything even remotely promising, so I'm going to say that it's not possible.
I did find text-overflow: -o-ellipsis-lastline
, but it only works in Opera: http://people.opera.com/dstorey/text/text-overflow.html (mirror: http://jsbin.com/exugux/)
There's also a similar WebKit-only solution: http://dropshado.ws/post/1015351370/webkit-line-clamp
Solution 2 - Html
You can do it with css. It only works in webkit browsers but has a fallback for the other ones.
use :
display: -webkit-box;
-webkit-line-clamp: $lines-to-show;
-webkit-box-orient: vertical;
height: $font-size*$line-height*$lines-to-show; /* Fallback for non-webkit */
along with:
max-width: $maxwidth;
overflow: hidden;
text-overflow: ellipsis;
Here is the fiddle: demo
Solution 3 - Html
I'm posting this because I believe my solution is less complex than the popular one, which involves pseudo elements and float behaviour. I recently had to create a solution which would work in IE7, so pseudo elements weren't an option in the first place.
The technique involves 4 elements:
- A block level container which determines the maximum height of the contents
- An inline wrapper for the text content
- An ellipsis contained within the inline wrapper
- A 'fill' element, also inside the inline wrapper, that occludes the ellipsis when the text content doesn't exceed the dimensions of the container
As with previous CSS-only solutions, the technique demands a solid colour background or fixed position background image for the contents: the ellipsis needs to obscure parts of the text, and the fill needs to obscure the ellipsis. You can do a fancy gradient effect to make the text fade into the ellipsis, but I'll leave that cosmetic detail to discretion.
HTML structure
<!-- The block level container. `clamped-2` for 2 lines height -->
<p class="clamped clamped-2">
<!-- The inline wrapper -->
<span class="text">
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy
nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.
Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit
lobortis nisl ut aliquip ex ea commodo consequat.
<!-- The ellipsis, which can contain anything you want -
(a 'more' link, for example) -->
<span class="ellipsis">
…
</span>
<!-- The fill, which covers the ellipsis when the text doesn't overflow -->
<span class="fill"></span>
</span>
</p>
CSS
body {
/* We need a solid background or background-position: fixed */
background: #fff;
/* You'll need to know the line height to clamp on line breaks */
line-height: 1.5;
}
.clamped {
overflow: hidden;
position: relative;
}
/* Clamp to 2 lines, ie line-height x 2:
Obviously any number of these classes can be written as needed
*/
.clamped-2 {
max-height: 3em;
}
/* The ellipsis is always at the bottom right of the container,
but when the text doesn't reach the bottom right...
*/
.clamped .ellipsis {
background: #fff;
bottom: 0;
position: absolute;
right: 0;
}
/* ...It's obscured by the fill, which is positioned at the bottom right
of the text, and occupies any remaining space.
*/
.clamped .fill {
background: #fff;
height: 100%;
position: absolute;
width: 100%;
}
Here's a fiddle demonstrating it: resize your browser's width or change the text to see it shift from ellipsis to no-ellipsis.
Aside from the arbitrary elegance factor, I believe this is more performant than the popular solution because it doesn't rely on floats (which require a lot of repainting) — absolute positioning is much simpler to compute since there are no inter-dependencies when calculating layout.
Solution 4 - Html
I wrote a javascript function to fix the multiline ellipsis problem
function ellipsizeTextBox(id) {
var el = document.getElementById(id);
var keep = el.innerHTML;
while(el.scrollHeight > el.offsetHeight) {
el.innerHTML = keep;
el.innerHTML = el.innerHTML.substring(0, el.innerHTML.length-1);
keep = el.innerHTML;
el.innerHTML = el.innerHTML + "...";
}
}
hope this helps!
Solution 5 - Html
I found a solution for multi-line cross-browser pure CSS ellipsis. I tried lots of solutions and only this one worked out only using CSS. I had a div with a dynamic width and had to set the height.
Here's the link: http://hackingui.com/front-end/a-pure-css-solution-for-multiline-text-truncation/
Solution 6 - Html
Modified the function by user1152475 so it works word by word (space delimited) rather than character by character.
function ellipsizeTextBox(id) {
var el = document.getElementById(id);
var wordArray = el.innerHTML.split(' ');
while(el.scrollHeight > el.offsetHeight) {
wordArray.pop();
el.innerHTML = wordArray.join(' ') + '...';
}
}
Note, for both solutions, the box must have a set height.
Solution 7 - Html
HTML offers no such feature, and this is very frustrating.
That's why i have developped a small library to deal with this issue. The library provides objects to modelize and perform letter-level text rendering. This should do just what you need:
Read more at http://www.samuelrossille.com/home/jstext for screenshot, tutorial, and dowload link.
Solution 8 - Html
As pointed out before there is a weird way to accomplish this with a webkit-box posted by David DeSandro:
elements_to_style {
display: -webkit-box;
overflow : hidden;
text-overflow: ellipsis
-webkit-line-clamp: number_of_lines_you_want;
-webkit-box-orient: vertical;
}
Solution 9 - Html
Hey you can do it this way using css.
For Chrome & Safari
.block-with-text {
overflow: hidden;
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
}
For Firefox & Internet explorer
* styles for '...' */
.block-with-text {
/* hide text if it more than N lines */
overflow: hidden;
/* for set '...' in absolute position */
position: relative;
/* use this value to count block height */
line-height: 1.2em;
/* max-height = line-height (1.2) * lines max number (3) */
max-height: 3.6em;
/* fix problem when last visible word doesn't adjoin right side */
text-align: justify;
/* place for '...' */
margin-right: -1em;
padding-right: 1em;
}
/* create the ... */
.block-with-text:before {
/* points in the end */
content: '...';
/* absolute position */
position: absolute;
/* set position to right bottom corner of block */
right: 0;
bottom: 0;
}
/* hide ... if we have text, which is less than or equal to max lines */
.block-with-text:after {
/* points in the end */
content: '';
/* absolute position */
position: absolute;
/* set position to right bottom corner of text */
right: 0;
/* set width and height */
width: 1em;
height: 1em;
margin-top: 0.2em;
/* bg color = bg color under block */
background: white;
}
Solution 10 - Html
just in case someone reach here, may this is a solution for you? pure css cross-browser. http://codepen.io/issactomatotan/pen/LkJbjO
<div style="position:relative;width:100%;max-height:40px;overflow:hidden;font-size:16px;line-height:20px;border:1px solid red;">
<p class="pp">asd asdasd asd asd asdasd a asdasd a sdasd asdasd asdaasd asd asd d asasas das dasdd asddasd asdasd asdsdasd asd<span class="bb"></span></p>
Solution 11 - Html
I've fiddled with most of these solutions and your best bet is to use the solid clamp.js plugin. It works in all environments and has a tiny footprint minified (3K).
Solution 12 - Html
.minHeightg {
height: 5.6rem !important;
width: 20%;
}
.productOverflow {
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
line-height: 16px;
/* fallback */
max-height: 3.6rem;
/* fallback */
-webkit-line-clamp: 3;
/* number of lines to show */
-webkit-box-orient: vertical;
}
/*firefox*/
@-moz-document url-prefix() {
.productOverflow {
overflow: hidden;
text-overflow: ellipsis;
display: -moz-box !important;
line-height: 16px;
/* fallback */
max-height: 3.6rem;
/* fallback */
-moz-line-clamp: 3;
/* number of lines to show */
-moz-box-orient: vertical;
}
}
<div class="minHeightg">
<p class="productOverflow">Some quick example text to build on the card title .</p>
</div>