314

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. */
+--------------------+
Sjoerd
  • 74,049
  • 16
  • 131
  • 175
Ovilia
  • 7,066
  • 12
  • 47
  • 70
  • 3
    If these are each separate lines, you really only need to worry about doing one line and repeating the functionality for each line. If these lines all belong to the same sentence, you should probably keep the ellipsis only on the last line. If you use an ellipsis partway through a sentence, you're essentially making a hole in your sentence. – Wex Jun 03 '11 at 04:58
  • related http://stackoverflow.com/questions/802175/truncating-long-strings-with-css-feasible-yet – Adriano Jun 13 '14 at 07:56
  • 4
    a good article on this subject http://css-tricks.com/line-clampin/ – Adriano Jun 13 '14 at 14:20
  • Please see following link for my answer: http://stackoverflow.com/questions/536814/insert-ellipsis-into-html-tag-if-content-too-wide – Shishir Arora Sep 22 '14 at 09:25
  • I answered this in very good detail with a [pure CSS solution here](https://stackoverflow.com/a/24942428/1589397). It works reliably. As mentioned in that reply, this is much easier to achieve with Javascript, but if that's off the table, [this works](https://stackoverflow.com/a/24942428/1589397). – dashard Dec 10 '18 at 20:21
  • As of 2019, there is now official CSS spec https://caniuse.com/#search=line-clamp implemented by all major browsers – Evgeny Dec 03 '19 at 19:04

16 Answers16

86

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

There also some preformance tests.

Milan Jaros
  • 1,107
  • 17
  • 24
Jim Thomas
  • 1,658
  • 11
  • 7
  • 61
    I haven't seen any pure css solutions to this requirement – Jim Thomas Jun 03 '11 at 05:23
  • @Ovilia note that Jim's solution also includes a jQuery plugin called jquery.autoellipsis.js, you'll have to download an include that separately – Jeff Jun 03 '11 at 17:47
  • @Olivia You will also need to include the main jQuery library before the plugin. If you're not familiar with that there's documentation here: http://docs.jquery.com/Main_Page . If you have included that, can you post the code that is not working for you? – Jim Thomas Jun 06 '11 at 04:30
  • @Ovilia I had the same problem. The problem turned out to be that I was executing ellipsis right after putting the value in the element. Once I put a timeout in place to delay the call to ellipsis everything worked. I assume the dom and all the needed metrics were not yet fully updated when the function was being called. – bladnman Nov 01 '12 at 23:48
  • 7
    css multiline elipsis tutorial : http://www.mobify.com/dev/multiline-ellipsis-in-pure-css/ – Julien Apr 07 '13 at 21:31
  • 2
    Dear people from the future: this plugin is my favorite, as it allows for toggling display of the hidden text. [http://keith-wood.name/more.html](http://keith-wood.name/more.html) – brichins Jun 17 '13 at 16:24
  • 1
    All libraries I've added are good. The performance tests can help you to decide but I'd like to mention that we are usually implementing dotdotdot because of it's wide range of configuration and clean code - easy to modify. (Note, this is just personal point of view - which doesn't belong to answer.) – Milan Jaros Dec 10 '14 at 13:29
  • Also to the people of the future: I found https://plugins.jquery.com/collapser/ to be effective where others options listed here were not. – phils May 26 '22 at 09:59
59

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.

balpha
  • 50,022
  • 18
  • 110
  • 131
  • 10
    You don't really need the 4 html elements, provided `your text` is wrapped with `

    ` tags (as they should be), then you can use `.ellipsify p:before` and `.ellipsify p:after` then of course you need `.ellipsify p:before{content:"\2026";}` the `\2026` is the code for the ellipsis, also, may need `content:" ";` as they may not work for the empty elements.

    – Val Feb 12 '13 at 11:49
  • 2
    Although I don't think this answer will suit many situations, At least a non-plugin, non-JavaScript answer is provided. That and the ingenuity that went into the construction of this answer is why I am `+1`ing it. – VoidKing Jul 23 '13 at 16:13
  • @MichalStefanow Just one -- the one I created it for: The descriptions on app "cards" on Apptivate.MS, e.g. see http://apptivate.ms/users/1141291/blynn. – balpha Nov 12 '13 at 13:50
  • @Pavlo, I really like your solution. But it seems to work with given standard text only, not if I load text out of a db, cause the script then does not know the outerHeight of the loaded text? – JonSnow Jan 07 '15 at 11:48
  • 2
    @SchweizerSchoggi, pseudo-elements or not, this solution doesn't rely on JS. It shouldn't matter where you get the text from if you implement it correctly. – Pavlo Jan 07 '15 at 13:07
45

Here's a recent css-tricks article which discusses this.

Some of the solutions in the above article (which are not mentioned here) are

1) -webkit-line-clamp and 2) Place an absolutely positioned element to the bottom right with fade out

Both methods assume the following markup:

<div class="module"> /* Add line-clamp/fade class here*/
  <p>Text here</p>
</div>

with css

.module {
  width: 250px;
  overflow: hidden;
}

1) -webkit-line-clamp

line-clamp FIDDLE (..for a maximum of 3 lines)

.line-clamp {
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;  
  max-height: 3.6em; /* I needed this to get it to work */
}

2) fade out

Let's say you set the line-height to 1.2em. If we want to expose three lines of text, we can just make the height of the container 3.6em (1.2em × 3). The hidden overflow will hide the rest.

Fade out FIDDLE

p
{
    margin:0;padding:0;
}
.module {
  width: 250px;
  overflow: hidden;
  border: 1px solid green;
  margin: 10px;
}

.fade {
  position: relative;
  height: 3.6em; /* exactly three lines */
}
.fade:after {
  content: "";
  text-align: right;
  position: absolute;
  bottom: 0;
  right: 0;
  width: 70%;
  height: 1.2em;
  background: linear-gradient(to right, rgba(255, 255, 255, 0), rgba(255, 255, 255, 1) 50%);
}

Solution #3 - A combination using @supports

We can use @supports to apply webkit's line-clamp on webkit browsers and apply fade out in other browsers.

@supports line-clamp with fade fallback fiddle

<div class="module line-clamp">
  <p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.</p>
</div>

CSS

.module {
  width: 250px;
  overflow: hidden;
  border: 1px solid green;
  margin: 10px;
}

.line-clamp {
      position: relative;
      height: 3.6em; /* exactly three lines */
    }
.line-clamp:after {
      content: "";
      text-align: right;
      position: absolute;
      bottom: 0;
      right: 0;
      width: 70%;
      height: 1.2em;
      background: linear-gradient(to right, rgba(255, 255, 255, 0), rgba(255, 255, 255, 1) 50%);
 }

@supports (-webkit-line-clamp: 3) {
    .line-clamp {
        display: -webkit-box;
        -webkit-line-clamp: 3;
        -webkit-box-orient: vertical;  
        max-height:3.6em; /* I needed this to get it to work */
        height: auto;
    }
    .line-clamp:after {
        display: none;
    }
}
Danield
  • 121,619
  • 37
  • 226
  • 255
34

The link below provides a pure HTML / CSS solution to this problem.

Browser support - as stated in the article:

So far we have tested on Safari 5.0, IE 9 (must be in standards mode), Opera 12 and Firefox 15.

Older browsers will still work quite well, as the meat of the layout is in normal positioning, margin and padding properties. if your platform is older (e.g. Firefox 3.6, IE 8), you can use the method but redo the gradient as a standalone PNG image or DirectX filter.

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

the css:

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: -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); }

the html:

<div class="ellipsis">
    <div>
        <p>Call me Ishmael.  Some years ago &ndash; never mind how long precisely &ndash; 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 &ndash; then, I account it high time to get to sea as soon as I can.</p>  
    </div>
</div>

the fiddle

(resize browser's window for testing)

Adriano
  • 19,463
  • 19
  • 103
  • 140
Kevin
  • 407
  • 4
  • 7
22

After looking over the W3 spec for text-overflow, I don't think this is possible using only CSS. Ellipsis is a new-ish property, so it probably hasn't received much usage or feedback as of yet.

However, this guy appears to have asked a similar (or identical) question, and someone was able to come up with a nice jQuery solution. You can demo the solution here: http://jsfiddle.net/MPkSF/

If javascript is not an option, I think you may be out of luck...

Community
  • 1
  • 1
Jeff
  • 12,147
  • 10
  • 51
  • 87
  • 3
    New-ish? MSIE supported it since IE6. Today, **all** browsers support it, *except Firefox*. – Christian Apr 24 '12 at 09:13
  • I would call any CSS3 property that is not globally implemented "new-ish". It's just a matter of semantics. Also, do you realize you're commenting on a post that's almost a year old? – Jeff Apr 24 '12 at 13:41
  • 5
    It's not CSS3, it's been there for ages and widely adopted. Only the specification *might* be considered new. Also, if SO didn't want comments on old threads, they could have disabled it. – Christian Apr 24 '12 at 19:24
10

Just want to add to this question for completeness sake.

Matt
  • 3,617
  • 2
  • 27
  • 39
  • Looks like `-o-ellipsis-lastline` may have been removed when Opera switched to WebKit. Leaving bullet for historical purposes. – Matt Jul 14 '15 at 21:27
8

Great question... I wish there was an answer, but this is the closest you can get with CSS these days. No ellipsis, but still pretty usable.

overflow: hidden;
line-height: 1.2em;
height: 3.6em;      // 3 lines * line-height
Adam Fraser
  • 6,255
  • 10
  • 42
  • 54
  • actually, Kevin's answer is the closest you can get with CSS these days http://stackoverflow.com/a/14248844/759452 – Adriano Mar 17 '15 at 10:39
7

I've found this css (scss) solution that works quite well. On webkit browsers it shows the ellipsis and on other browsers it just truncates the text. Which is fine for my intended use.

$font-size: 26px;
$line-height: 1.4;
$lines-to-show: 3;

h2 {
  display: block; /* Fallback for non-webkit */
  display: -webkit-box;
  max-width: 400px;
  height: $font-size*$line-height*$lines-to-show; /* Fallback for non-webkit */
  margin: 0 auto;
  font-size: $font-size;
  line-height: $line-height;
  -webkit-line-clamp: $lines-to-show;
  -webkit-box-orient: vertical;
  overflow: hidden;
  text-overflow: ellipsis;
}

An example by the creator: http://codepen.io/martinwolf/pen/qlFdp

Nikola Lajic
  • 3,985
  • 28
  • 34
7

There are many answers here but I needed one that was:

  • CSS Only
  • Future-proof (gets more compatible with time)
  • Not going to break words apart (only breaks on spaces)

The caveat is that it doesn't provide an ellipsis for the browsers that don't support the -webkit-line-clamp rule (currently IE, Edge, Firefox) but it does use a gradient to fade their text out.

.clampMe {
  position: relative;
  height: 2.4em; 
  overflow: hidden;
}

.clampMe:after {
  content: "";
  text-align: right;
  position: absolute;
  bottom: 0;
  right: 0;
  width: 50%;
  height: 1.2em; /* Just use multiples of the line-height */
  background: linear-gradient(to right, rgba(255, 255, 255, 0), rgba(255, 255, 255, 1) 80%);
}

/* Now add in code for the browsers that support -webkit-line-clamp and overwrite the non-supportive stuff */
@supports (-webkit-line-clamp: 2) {
  .clampMe {
      overflow: hidden;
      text-overflow: ellipsis;
      display: -webkit-box;
      -webkit-line-clamp: 2;
      -webkit-box-orient: vertical;
  }
  
  .clampMe:after {
    display: none;
  }
}
<p class="clampMe">There's a lot more text in here than what you'll ever see. Pellentesque habitant testalotish morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.</p>

You can see it in action in this CodePen and you can also see a Javascript version here (no jQuery).

NilsyNils
  • 451
  • 5
  • 3
6

Here is the closest solution I could get using just css.

HTML

<div class="ellipsis"> <span>...</span>
Hello this is Mr_Green from Stackoverflow. I love CSS. I live in CSS and I will never leave working on CSS even my work is on other technologies.</div>

CSS

div {
    height: 3em;
    line-height: 1.5em;
    width: 80%;
    border: 1px solid green;
    overflow: hidden;
    position: relative;
}
div:after {
    content:". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .  . . . . . . . . . . . . . . . . . . . . . . . . . . . .";
    background-color: white;
    color: white;
    display: inline;
    position: relative;
    box-shadow: 8px 1px 1px white;
    z-index: 1;
}
span {
    position: absolute;
    bottom: 0px;
    right: 0px;
    background-color: white;
}

Working Fiddle (resize the window to check)

Link to my blog for explanation

Updated Fiddle

I hope now some css expert would have got idea on how to make it perfect. :)

Mr_Green
  • 40,727
  • 45
  • 159
  • 271
  • That answer is giving me a stomach-ache. First of all, you don't use typographically available ellipsis… (it's a font symbol taking up one space). Compare http://www.smashingmagazine.com/2008/08/11/top-ten-web-typography-sins/ And by your solution, you can't really control where the ellipsis stays, so it can come to undesirable situations, like for dots in a row. – Volker E. Apr 17 '14 at 00:17
  • 1
    @VolkerE. Thanks for the information. Here is the [updated fiddle](http://jsfiddle.net/LJ62x/192/). please let me know if I am missing any point in your explanation. – Mr_Green Apr 17 '14 at 04:23
  • Great solution (the original one), but why not use `div::before` instead of that `span`? :) – Adam Oct 09 '15 at 09:14
  • @Adam there was some edge case, so I didn't use pseudo element. (_I don't remember it now_) – Mr_Green Oct 09 '15 at 11:41
4

Bit late to this party but I came up with, what I think, is a unique solution. Rather than trying to insert your own ellipsis through css trickery or js I thought i'd try and roll with the single line only restriction. So I duplicate the text for every "line" and just use a negative text-indent to make sure one line starts where the last one stops. FIDDLE

CSS:

#wrapper{
    font-size: 20pt;
    line-height: 22pt;
    width: 100%;
    overflow: hidden;
    padding: 0;
    margin: 0;
}

.text-block-line{
    height: 22pt;
    display: inline-block;
    max-width: 100%;
    overflow: hidden;
    white-space: nowrap;
    width: auto;
}
.text-block-line:last-child{
    text-overflow: ellipsis;
}

/*the follwing is suboptimal but neccesary I think. I'd probably just make a sass mixin that I can feed a max number of lines to and have them avialable. Number of lines will need to be controlled by server or client template which is no worse than doing a character count clip server side now. */
.line2{
    text-indent: -100%;
}
.line3{
    text-indent: -200%;
}
.line4{
    text-indent: -300%;
}

HTML:

<p id="wrapper" class="redraw">
    <span class="text-block-line line1">This text is repeated for every line that you want to be displayed in your element. This example has a max of 4 lines before the ellipsis occurs. Try scaling the preview window width to see the effect.</span>
    <span class="text-block-line line2">This text is repeated for every line that you want to be displayed in your element. This example has a max of 4 lines before the ellipsis occurs. Try scaling the preview window width to see the effect.</span>
    <span class="text-block-line line3">This text is repeated for every line that you want to be displayed in your element. This example has a max of 4 lines before the ellipsis occurs. Try scaling the preview window width to see the effect.</span>
    <span class="text-block-line line4">This text is repeated for every line that you want to be displayed in your element. This example has a max of 4 lines before the ellipsis occurs. Try scaling the preview window width to see the effect.</span>
</p>

More details in the fiddle. There is an issue with the browser reflowing that I use a JS redraw for and such so do check it out but this is the basic concept. Any thoughts/suggestions are much appreciated.

lupos
  • 374
  • 1
  • 9
  • 1
    I don't like the thought of duplicating every line of text. Furthermore - what if the text is dynamic - you won't know how many lines to add. That being said, +1 for this unique solution! – Danield Jan 09 '14 at 11:03
  • Thanks for the input :) Dynamic text isn't an issue. Its basically defining the max-height of the container on the template instead. If you want to limit it to 3 lines then make 3. My use case has a headline that can be 1-2 lines and an excerpt that can be 1-3. Those are known values. Doesn't matter how long the string is. Also if you do do this in a template situation and not static html you can have it handle the negative text-indent with an inline style so you don't need that big block of line1,line2,line3, etc. I may whip up a fiddle using js template as an example. – lupos Jan 09 '14 at 15:11
  • Would be helpful if breaking of words is not an issue in the project. – Mr_Green Apr 17 '14 at 04:28
4

thanks @balpha and @Kevin, I combine two method together.

no js needed in this method.

you can use background-image and no gradient needed to hide dots.

the innerHTML of .ellipsis-placeholder is not necessary, I use .ellipsis-placeholder to keep the same width and height with .ellipsis-more. You could use display: inline-block instead.

.ellipsis {
    overflow: hidden;
    position: relative;
}
.ellipsis-more-top {/*push down .ellipsis-more*/
    content: "";
    float: left;
    width: 5px;
}
.ellipsis-text-container {
    float: right;
    width: 100%;
    margin-left: -5px;
}
.ellipsis-more-container {
    float: right;
    position: relative;
    left: 100%;
    width: 5px;
    margin-left: -5px;
    border-right: solid 5px transparent;
    white-space: nowrap;
}
.ellipsis-placeholder {/*keep text around ,keep it transparent ,keep same width and height as .ellipsis-more*/
    float: right;
    clear: right;
    color: transparent;
}
.ellipsis-placeholder-top {/*push down .ellipsis-placeholder*/
    float: right;
    width: 0;
}
.ellipsis-more {/*ellipsis things here*/
    float: right;
}
.ellipsis-height {/*the total height*/
    height: 3.6em;
}
.ellipsis-line-height {/*the line-height*/
    line-height: 1.2;
}
.ellipsis-margin-top {/*one line height*/
    margin-top: -1.2em;
}
.ellipsis-text {
    word-break: break-all;
}
<div class="ellipsis ellipsis-height ellipsis-line-height">
    <div class="ellipsis-more-top ellipsis-height"></div>
    <div class="ellipsis-text-container">
        <div class="ellipsis-placeholder-top ellipsis-height ellipsis-margin-top"></div>
        <div class="ellipsis-placeholder">
           <span>...</span><span>more</span>
        </div>
        <span class="ellipsis-text">text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text </span>
    </div>
    <div class="ellipsis-more-container ellipsis-margin-top">
        <div class="ellipsis-more">
            <span>...</span><span>more</span>
        </div>
    </div>
</div>

jsfiddler

Defims
  • 233
  • 1
  • 2
  • 11
2
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical; 

see more click here

elrrrrrrr
  • 894
  • 8
  • 15
  • If your project doesn't require support for IE this is an excellent solution! https://caniuse.com/mdn-css_properties_-webkit-line-clamp – Dries Dec 17 '21 at 14:28
2

javascript solution will be better

  • get the lines number of text
  • toggle is-ellipsis class if the window resize or elment change

getRowRects

Element.getClientRects() works like this

enter image description here

each rects in the same row has the same top value, so find out the rects with different top value, like this

enter image description here

function getRowRects(element) {
    var rects = [],
        clientRects = element.getClientRects(),
        len = clientRects.length,
        clientRect, top, rectsLen, rect, i;

    for(i=0; i<len; i++) {
        has = false;
        rectsLen = rects.length;
        clientRect = clientRects[i];
        top = clientRect.top;
        while(rectsLen--) {
            rect = rects[rectsLen];
            if (rect.top == top) {
                has = true;
                break;
            }
        }
        if(has) {
            rect.right = rect.right > clientRect.right ? rect.right : clientRect.right;
            rect.width = rect.right - rect.left;
        }
        else {
            rects.push({
                top: clientRect.top,
                right: clientRect.right,
                bottom: clientRect.bottom,
                left: clientRect.left,
                width: clientRect.width,
                height: clientRect.height
            });
        }
    }
    return rects;
}

float ...more

like this

enter image description here

detect window resize or element changed

like this

enter image description here

enter image description here

enter image description here

Defims
  • 233
  • 1
  • 2
  • 11
0

I found a javascript trick, but you have to use the length of the string. Lets say you want 3 lines of width 250px, you can calculate the length per line i.e.

//get the total character length.
//Haha this might vary if you have a text with lots of "i" vs "w"
var totalLength = (width / yourFontSize) * yourNumberOfLines

//then ellipsify
function shorten(text, totalLength) {
    var ret = text;
    if (ret.length > totalLength) {
        ret = ret.substr(0, totalLength-3) + "...";
    }
    return ret;
}
Tremmillicious
  • 454
  • 4
  • 14
  • Most likely, we don't use fixed-width fonts everywhere. So this trick may fail in these situations. – Ovilia Aug 18 '14 at 02:04
0

a pure css method base on -webkit-line-clamp:

@-webkit-keyframes ellipsis {/*for test*/
    0% { width: 622px }
    50% { width: 311px }
    100% { width: 622px }
}
.ellipsis {
    max-height: 40px;/* h*n */
    overflow: hidden;
    background: #eee;

    -webkit-animation: ellipsis ease 5s infinite;/*for test*/
    /**
    overflow: visible;
    /**/
}
.ellipsis .content {
    position: relative;
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-box-pack: center;
    font-size: 50px;/* w */
    line-height: 20px;/* line-height h */
    color: transparent;
    -webkit-line-clamp: 2;/* max row number n */
    vertical-align: top;
}
.ellipsis .text {
    display: inline;
    vertical-align: top;
    font-size: 14px;
    color: #000;
}
.ellipsis .overlay {
    position: absolute;
    top: 0;
    left: 50%;
    width: 100%;
    height: 100%;
    overflow: hidden;

    /**
    overflow: visible;
    left: 0;
    background: rgba(0,0,0,.5);
    /**/
}
.ellipsis .overlay:before {
    content: "";
    display: block;
    float: left;
    width: 50%;
    height: 100%;

    /**
    background: lightgreen;
    /**/
}
.ellipsis .placeholder {
    float: left;
    width: 50%;
    height: 40px;/* h*n */

    /**
    background: lightblue;
    /**/
}
.ellipsis .more {
    position: relative;
    top: -20px;/* -h */
    left: -50px;/* -w */
    float: left;
    color: #000;
    width: 50px;/* width of the .more w */
    height: 20px;/* h */
    font-size: 14px;

    /**
    top: 0;
    left: 0;
    background: orange;
    /**/
}
<div class='ellipsis'>
    <div class='content'>
        <div class='text'>text text text text text text text text text text text text text text text text text text text text text </div>
        <div class='overlay'>
            <div class='placeholder'></div>
            <div class='more'>...more</div>
        </div>
    </div>
</div>
Defims
  • 233
  • 1
  • 2
  • 11