257

I know you can use a combination of CSS rules to make text end with ellipsis (...) when it's time to overflow (get out of parent's bounds).

Is it possible (feel free to just say, no) to achieve the same effect, but let the text wrap on more than one line?

Here's a demo.

div { width: 300px; height: 42px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } 

As you can see, the text ends with ellipsis when it goes wider than the div's width. However, there is still enough space for the text to wrap on a second line and go on. This is interrupted by white-space: nowrap, which is required for the ellipsis to work.

Any ideas?

P.S.: No JS solutions, pure CSS if possible.

4
  • What determines "there is space"? Is everything including the font height in set pixels? What would happen if an end user increased the font size at their browser? Commented Apr 9, 2013 at 18:22
  • @JoelEtherton I suppose that's up for the browser to decide and yes, everything is in pixels in my case. Commented Apr 9, 2013 at 18:26
  • This can be a good solution: stackoverflow.com/questions/6222616/… Commented Feb 28, 2014 at 8:00
  • This is a really nice read hackingui.com/front-end/… Commented Dec 4, 2017 at 14:20

19 Answers 19

416

Easy CSS properties can do the trick. The following is for a three-line ellipsis.

display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; text-overflow: ellipsis; 
Sign up to request clarification or add additional context in comments.

9 Comments

this does not work in firefox. only chrome, safari, and opera
according to caniuse, it says that "it is unlikely that other browsers will support the property as-is". So heads up.
Works on Firefox, Chrome, Safari
Seems to have great support now: caniuse.com/#search=line-clamp
Firefox now supports all of this with the -webkit prefixes
|
105

Take a look at this pure css version: http://codepen.io/martinwolf/pen/qlFdp

h2 { display: -webkit-box; max-width: 400px; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; text-overflow: ellipsis; }
<h2>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et.</h2>

5 Comments

That's really cool, too bad it's webkit only. Here's an interesting article on the matter: css-tricks.com/line-clampin
Why do you declare two text-overflow and display rules?
A big WoooW. Ive never seen before line-clamp
Just FYI, this works fine in Firefox these days, as well. Great solution!
only 1 question, when i have one line or two lines of text i want them centered, how do I do that,if I add display flex i lose the ellipsis, seems like this works only if display: -webkit box is set
51

I'm not sure if you have seen this article, but Chris Coyier's excellent CSS-Tricks.com posted a link to this a while back and it's a pure CSS solution that accomplishes exactly what you seek.

(Click to View on CodePen)

html, body, p { margin: 0; padding: 0; font-family: sans-serif; } .ellipsis { overflow: hidden; height: 200px; line-height: 25px; margin: 20px; border: 5px solid #AAA; } .ellipsis:before { content: ""; float: left; width: 5px; height: 200px; } .ellipsis>*:first-child { float: right; width: 100%; margin-left: -5px; } .ellipsis:after { content: "\02026"; box-sizing: content-box; -webkit-box-sizing: content-box; -moz-box-sizing: content-box; float: right; position: relative; top: -25px; left: 100%; width: 3em; margin-left: -3em; padding-right: 5px; text-align: right; background-size: 100% 100%; /* 512x1 image,gradient for IE9. Transparent at 0% -> white at 50% -> white at 100%.*/ background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAgAAAAABCAMAAACfZeZEAAAABGdBTUEAALGPC/xhBQAAAwBQTFRF////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AAAA////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////wDWRdwAAAP90Uk5TgsRjMZXhS30YrvDUP3Emow1YibnM9+ggOZxrBtpRRo94gxItwLOoX/vsHdA2yGgL8+TdKUK8VFufmHSGgAQWJNc9tk+rb5KMCA8aM0iwpWV6dwP9+fXuFerm3yMs0jDOysY8wr5FTldeoWKabgEJ8RATG+IeIdsn2NUqLjQ3OgBDumC3SbRMsVKsValZplydZpZpbJOQco2KdYeEe36BDAL8/vgHBfr2CvTyDu8R7esU6RcZ5ecc4+Af3iLcJSjZ1ivT0S/PMs3LNck4x8U7wz7Bv0G9RLtHuEq1TbJQr1OtVqqnWqRdoqBhnmSbZ5mXapRtcJGOc4t2eYiFfH9AS7qYlgAAARlJREFUKM9jqK9fEGS7VNrDI2+F/nyB1Z4Fa5UKN4TbbeLY7FW0Tatkp3jp7mj7vXzl+4yrDsYoVx+JYz7mXXNSp/a0RN25JMcLPP8umzRcTZW77tNyk63tdprzXdmO+2ZdD9MFe56Y9z3LUG96mcX02n/CW71JH6Qmf8px/cw77ZvVzB+BCj8D5vxhn/vXZh6D4uzf1rN+Cc347j79q/zUL25TPrJMfG/5LvuNZP8rixeZz/mf+vU+Vut+5NL5gPOeb/sd1dZbTs03hBuvmV5JuaRyMfk849nEM7qnEk6IHI8/qn049hB35QGHiv0yZXuMdkXtYC3ebrglcqvYxoj1muvC1nDlrzJYGbpcdHHIMo2FwYv+j3QAAOBSfkZYITwUAAAAAElFTkSuQmCC); background: -webkit-gradient(linear, left top, right top, from(rgba(255, 255, 255, 0)), to(white), color-stop(50%, white)); background: -moz-linear-gradient(to right, rgba(255, 255, 255, 0), white 50%, white); background: -o-linear-gradient(to right, rgba(255, 255, 255, 0), white 50%, white); background: -ms-linear-gradient(to right, rgba(255, 255, 255, 0), white 50%, white); background: linear-gradient(to right, rgba(255, 255, 255, 0), white 50%, white); }
<div class="ellipsis"> <div> <p> Call me Ishmael. Some years ago – never mind how long precisely – having little or no money in my purse, and nothing particular to interest me on shore, I thought I would sail about a little and see the watery part of the world. It is a way I have of driving off the spleen, and regulating the circulation. Whenever I find myself growing grim about the mouth; whenever it is a damp, drizzly November in my soul; whenever I find myself involuntarily pausing before coffin warehouses, and bringing up the rear of every funeral I meet; and especially whenever my hypos get such an upper hand of me, that it requires a strong moral principle to prevent me from deliberately stepping into the street, and methodically knocking people's hats off – then, I account it high time to get to sea as soon as I can. </p> </div> </div>

Of course, being a pure CSS solution means that it's also a pretty complicated one, but it works cleanly and elegantly. I will assume that Javascript is out of the question because this is much easier to achieve (and arguably more degradable) with Javascript.

As an added bonus, there's a downloadable zip file of the complete process (if you want to understand it and all), but also a SASS mixin file so that you can fold it into your process easy-peasy.

Hope this helps!

http://www.mobify.com/blog/multiline-ellipsis-in-pure-css/

6 Comments

I just clicked on your Codepen link on an Android phone and it worked in Firefox. What platform/browser is it not working in?
uploady.com/#!/download/kAwBXv1CqXg/PU68wrP6QzGgydlS I'm using chrome and there are no ellipsis in the preview. Keep on adding lines of text, nothing happens. After how many lines will it start showing ellipsis ?
In the uploady link you posted, the text clearly had not yet overflowed the container. The text has to be too much for the fixed container to display before the ellipses will appear. Just keep adding text to see the effect.
@MarcosPérezGude -- doesn't surprise me. Alluded to that with >>"Of course, being a pure CSS solution means that it's also a pretty complicated one…"<<
|
24

Use this if above is not working

 display: -webkit-box; max-width: 100%; margin: 0 auto; -webkit-line-clamp: 2; /* autoprefixer: off */ -webkit-box-orient: vertical; /* autoprefixer: on */ overflow: hidden; text-overflow: ellipsis; 

1 Comment

This is Webkit only.
15

Css below should do the trick.

After the second line the, text will contain ...

line-height: 1em; max-height: 2em; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; 

1 Comment

this worked nicely but I had to add overflow:hidden
5

It seems more elegant combining two classes. You can drop two-lines class if only one row need see:

.ellipse { white-space: nowrap; display:inline-block; overflow: hidden; text-overflow: ellipsis; } .two-lines { -webkit-line-clamp: 2; display: -webkit-box; -webkit-box-orient: vertical; white-space: normal; } .width{ width:100px; border:1px solid hotpink; }
 <span class='width ellipse'> some texts some texts some texts some texts some texts some texts some texts </span> <span class='width ellipse two-lines'> some texts some texts some texts some texts some texts some texts some texts </span>

Comments

4

My solution reuses the one of amcdnl, but my fallback consist of using a height for the text container:

.my-caption h4 { display: -webkit-box; margin: 0 auto; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; text-overflow: ellipsis; height: 40px;/* Fallback for non-webkit */ } 

2 Comments

-webkit-line-clamp does not work for IE11, Edge, or Firefox.
@Garry, you are right, at the time you would have needed a JS fix, but it now works fine. caniuse.com/#search=webkit-line-clamp
2

In my angular app the following style worked for me to achieve ellipsis on the overflow of text on the second line:

 <div style="height:45px; overflow: hidden; position: relative;"> <span class=" block h6 font-semibold clear" style="overflow: hidden; text-overflow: ellipsis; display: -webkit-box; line-height: 20px; /* fallback */ max-height: 40px; /* fallback */ -webkit-line-clamp: 2; /* number of lines to show */ -webkit-box-orient: vertical;"> {{ event?.name}} </span> </div> 

Hope it helps someone.

1 Comment

Thank You. Works for me in angular. Is there a way if the text is one line then add an empty line?
2

For those working in scss, you need to add !autoprefixer to the start of the comment so that it is preserved for postcss:

I faced that issue that's why posting it here

line-height: 1em; max-height: 2em; display: -webkit-box; /*! autoprefixer: off */ -webkit-box-orient: vertical; -webkit-line-clamp: 2; 

Reference

Comments

2

There are 2 possible solutions. The one in the top answer and a new approach using the new line height unit - e.g. max-height: 3lh

Neither is perfect:

Webkit Line Clamp can truncate words with no ellipsis (except on the final line)

Max Line Height shows an ellipsis on all lines if needed but often omits the ellipsis on the final line (see snippet)

For short words with a wide container Webkit Line Clamp is best

For long words with a narrow container prefer the Max Line Height approach

.common { overflow: hidden; width: 100px; margin-bottom: 10px; background: cyan; } .webkit-line-clamp-3-lines { display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; } .max-height-3lh { max-height: 3lh; text-overflow: ellipsis; }
<h4>Webkit Line Clamp</h4> PASS <div class="common webkit-line-clamp-3-lines"> 00000 11111 22222 33333 44444 55555 66666 77777 88888 99999 </div> FAIL: words truncated with no ellipsis on lines 1 and 2 <div class="common webkit-line-clamp-3-lines"> wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww </div> <h4>Max Line Height</h4> FAIL: no ellipsis on line 3 <div class="common max-height-3lh"> 00000 11111 22222 33333 44444 55555 66666 77777 88888 99999 </div> PASS <div class="common max-height-3lh"> wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww </div>

Comments

1

Base on an answer I saw in stackoveflow, I created this LESS mixin (use this link to generate the CSS code):

.max-lines(@lines: 3; @line-height: 1.2) { overflow: hidden; text-overflow: ellipsis; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: @lines; line-height: @line-height; max-height: @line-height * @lines; } 

Usage

.example-1 { .max-lines(); } .example-2 { .max-lines(3); } .example-3 { .max-lines(3, 1.5); } 

Comments

1

You can use a dissolved out effect instead of ellipsis, pure CSS and looks more professional:

 <div style="width: 293px; height:48px; overflow: hidden; "> More than two line of text goes here-More than two line of text goes here </div> <div style="position: relative; top: -24px; width: 293px; height:24px; background: linear-gradient(90deg, rgba(255,0,0,0) 40%, rgba(255,255,255,1) 99%);"> </div> 

Here I have assumed your background color is white.

Comments

0
 text-overflow: ellipsis; overflow: hidden; text-overflow: ellipsis; display: -webkit-box; line-height: 36px; max-height: 18px; -webkit-line-clamp: 2; -webkit-box-orient: vertical; 

I've found a combo of both line-clamp and line-height works :D

Comments

0

Restricting to few lines will work in almost all browsers, but an ellipsis(3 dots) will not be displayed in Firefox & IE. Demo - http://jsfiddle.net/ahzo4b91/1/

div { width: 300px; height: 2.8em; line-height: 1.4em; display: flex; -webkit-line-clamp: 2; display: -webkit-box; -webkit-box-orient: vertical; overflow: hidden; } 

Comments

0

Here's a Material-UI faded text effect based on Mahan Lamei's suggestion:

Create the overlay style
const useStyles = makeStyles((theme) => createStyles({ fadeText: { background: `linear-gradient( 180deg, #FFFFFF00, 0%, #FFFFFF06 30%, #FFFFFFFF 100%)`, pointerEvents: "none", } }) ) 
Next overlay a gradient on a fixed-height nested Box component
<Grid container justify="center"> <Grid item xs={8} sm={6} md={4}> <Box> <Box component="div" overflow="hidden" display="flex" flexDirection="column" fontFamily="Roboto" fontSize="body1.fontSize" fontWeight="fontWeightLight" textAlign="justify" height={['8rem']} > <Box display="flex"> Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. </Box> </Box> <Box className={classes.fadeText} display="block" position="relative" top="-4rem" height="4rem" /> </Box> </Grid> </Grid> 

Working demo: Codesandbox

MUI's default theme uses abbreviated CSS colors (#FFF) so if you want to set your gradients based on the current theme you will need to override them with the full six character variants.

Example: using theme to set the gradient (e.g. based on the light/dark theme):

const useStyles = makeStyles((theme: Theme) => createStyles({ fadeText: { background: `linear-gradient( 180deg, ${theme.palette.background.paper}00 0%, ${theme.palette.background.paper}06 30%, ${theme.palette.background.paper}FF 100%)` } }) ) 

Edit: Updated to include Tony Bogdanov's suggestion

2 Comments

One cool addition would be to add pointer-events: none on the faded overlay element. This way you'll be able to select & work with the text under it.
Thanks Tony, awesome suggestion. I updated the code to include this.
0

this is the solution that works for me as I understand everyone desired result could be different.

display: -webkit-box; min-height: 109.2px; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; text-overflow: ellipsis; line-height: 1.625; /* as per desire */ 

Comments

-1

This is a total hack, but it works:

http://jsfiddle.net/2wPNg/

div { width: 30%; float: left; margin-right: 2%; height: 94px; overflow: hidden; position: relative; } div:after { display: block; content: '...'; width: 1em; height: 1.5em; background: #fff; position: absolute; bottom: -6px; right: 0; } 

It does have problems.... it might cut off a letter awkwardly, and it will probably have some weird results on a responsive site.

1 Comment

This will not right solution because if content is smaller then also it add '...' in the end. Fiddle : jsfiddle.net/2wPNg
-1

Here is a simple script to manage the ellipsis using jQuery. It inspects the real height of the element and it creates a hidden original node and a truncated node. When the user clicks it switches between the two versions.

One of the great benefits is that the "ellipsis" is near the last word, as expected.

If you use pure CSS solutions the three dots appears distant from the last word.

function manageShortMessages() { $('.myLongVerticalText').each(function () { if ($(this)[0].scrollHeight > $(this)[0].clientHeight) $(this).addClass('ellipsis short'); }); $('.myLongVerticalText.ellipsis').each(function () { var original = $(this).clone().addClass('original notruncation').removeClass('short').hide(); $(this).after(original); //debugger; var shortText = ''; shortText = $(this).html().trim().substring(0, 60) + '...'; $(this).html(shortText); }); $('.myLongVerticalText.ellipsis').click(function () { $(this).hide(); if ($(this).hasClass('original')) { $(this).parent().find('.short').show(); } else { $(this).parent().find('.original').show(); } }); } manageShortMessages();
div { border:1px solid red; margin:10px; } div.myLongVerticalText { height:30px; width:450px; } div.myLongVerticalText.ellipsis { cursor:pointer; } div.myLongVerticalText.original { display:inline-block; height:inherit; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <body> <div class="myLongVerticalText"> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse sit amet quam hendrerit, sagittis augue vel, placerat erat. Aliquam varius porta posuere. Aliquam erat volutpat. Phasellus ullamcorper malesuada bibendum. Etiam fringilla, massa vitae pulvinar vehicula, augue orci mollis lorem, laoreet viverra massa eros id est. Phasellus suscipit pulvinar consectetur. Proin dignissim egestas erat at feugiat. Aenean eu consectetur erat. Nullam condimentum turpis eu tristique malesuada. Aenean sagittis ex sagittis ullamcorper auctor. Sed varius commodo dui, nec consectetur ante condimentum et. Donec nec blandit mi, vitae blandit elit. Phasellus efficitur ornare est facilisis commodo. Donec convallis nunc sed mauris vehicula, non faucibus neque vehicula. Donec scelerisque luctus dui eu commodo. Integer eu quam sit amet dui tincidunt pharetra eu ac quam. Quisque tempus pellentesque hendrerit. Sed orci quam, posuere eu feugiat at, congue sed felis. In ut lectus gravida, volutpat urna vitae, cursus justo. Nam suscipit est ac accumsan consectetur. Donec rhoncus placerat metus, ut elementum massa facilisis eget. Donec at arcu ac magna viverra tincidunt. </div> <div class="myLongVerticalText"> One Line Lorem ipsum dolor sit amet. </div> </body>

4 Comments

If you downvote this solution, please explain why here, I'll appreciate it.
OP asked for CSS solution and you offered jQuery?
I missed that it was a strong requirement the absence of javascript, in my case the pure CSS solution presented rendering problems, the jQuery solution gave me more control over the final rendering and the ellipsis position.
Absolutely agree. In my answer I noted that this was infinitely easier to achieve with JS.
-3

Not sure what your target is, but do you want the text to come on the second line?

Here is your jsFiddle: http://jsfiddle.net/8kvWX/4/ just removed the following:

 white-space:nowrap; 

Im not sure if this is what your are looking for or not.

Regards,

Mee

3 Comments

He wants the ellipsis at the end of the second line, which is not that easy to do without JavaScript...
Right, as I found another person asking to have the lines on the second line and his CSS was pretty much the same as yours but the class was pointing to a ul tag instead. Anyways, sorry Tony. I will have a look on it again and update my answer if I get successful.
well i think that the best solution is the one from @Itay Gal. As far as I saw that one is working.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.