user1227914
user1227914

Reputation: 3514

How can I do text-overflow: ellipsis on two lines?

I have a container where the text may expand to two lines and it's 40px in height, with an 18px font size. When I do:

text-overflow: ellipsis;
white-space: nowrap;

Then the dotted line shows correctly but it gets cut off on one line. When I do just the:

text-overflow: ellipsis;

Then it correctly shows the 2 lines but there's no "..." at the end. How do I achieve this so it correctly uses both lines AND finishes with "..." on the second line?

Upvotes: 11

Views: 38955

Answers (5)

VamsiKaja
VamsiKaja

Reputation: 406

You can do it using -webkit-line-clamp. But a hack is needed. You need to set the height of the div such that it can accommodate only two lines.

See this codepen https://codepen.io/VamsiKaja/pen/xYZVzY

HTML file :

<p>Pellentesque habitant morbi tristique senectus et netus et</p>

CSS file :

p {
    width:250px;  
    font-size:20px;
    margin:1em;
    height:50px;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

Upvotes: 9

irfan shaikh
irfan shaikh

Reputation: 67

Below solution worked for me.

.cell {
  display: -webkit-box;
  overflow: hidden;
  text-align: center;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
}

Upvotes: 0

Defims
Defims

Reputation: 243

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>

Upvotes: -1

puiu
puiu

Reputation: 726

Just want to add my two cents. The closest pure CSS solution that works is the -webkit-line-clamp method but is limited to webkit browsers and is the remnant of an old flexbox implementation (which may be removed in the future).

Perhaps you should reconsider if you really require an ellipses on vertically overflowed text.

I suggest instead use a scroll-able text box instead. I believe this is the best solution because of these three reasons:

  1. Works in every major browser
  2. No css workarounds, hacks, or javascript involved
  3. Communicates well to the user that text is cutoff but gives them the option to scroll through it if they wish - plus, users are already accustomed to vertical scroll bars

Here is sample code for a text box:

.element {
  display: inline-block;
  height: 200px;
  overflow-y: auto;

  /* this is to preserve text containing new lines */
  white-space: pre-line;
}

If I had to choose though, I would use a javascript solution along the lines of Succint which deletes words after a certain amount and appends an ... at the end. This is great if you use React because you can implement all the code required inside the component as a function and if you need the original text you still have it as a props value.

Upvotes: 0

Rick Hitchcock
Rick Hitchcock

Reputation: 35670

Add a span to the container, which will hold the text:

<div class="container">
  <span>text...</span>
</span>

Add this CSS:

.container {
   overflow: hidden;
   position: relative;
   background: white;   //or other color
}

.container:after {
  content: '...';       //the ellipsis
  position: absolute;   //positioned in bottom-right
  bottom: 0;            //...
  right: 0;             //...
  padding: 0 0.3em;     //give some separation from text
  background: inherit;  //same color as container
}

.container span:after {
  content: '\0000a0';   //a space
  position: absolute;   //to cover up ellipsis if needed
  width: 1000px;        //...
  z-index: 1;           //...
  background: white;    //must match container's color.  can't use inherit here.
}

Fiddle

Resize the container, and you'll see that the ellipsis displays only as necessary.

Should work in all modern browsers.

Upvotes: 5

Related Questions