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?
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?
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
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
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:
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.
<!-- 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>
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.
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!
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/
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.
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.
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;
}
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;
}
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>
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).
.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>