Applying an ellipsis to multiline text

2018-12-31 01:44发布

Is there a solution to add ellipsis on last line inside a div with a fluid height (20%)?

I found the -webkit-line-clamp function in CSS, but in my case the line number will be depending on window size.

p {
    width:100%;
    height:20%;
    background:red;
    position:absolute;
}
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla sed dui felis. Vivamus vitae pharetra nisl, eget fringilla elit. Ut nec est sapien. Aliquam dignissim velit sed nunc imperdiet cursus. Proin arcu diam, tempus ac vehicula a, dictum quis nibh. Maecenas vitae quam ac mi venenatis vulputate. Suspendisse fermentum suscipit eros, ac ultricies leo sagittis quis. Nunc sollicitudin lorem eget eros eleifend facilisis. Quisque bibendum sem at bibendum suscipit. Nam id tellus mi. Mauris vestibulum, eros ac ultrices lacinia, justo est faucibus ipsum, sed sollicitudin sapien odio sed est. In massa ipsum, bibendum quis lorem et, volutpat ultricies nisi. Maecenas scelerisque sodales ipsum a hendreritLorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla sed dui felis. Vivamus vitae pharetra nisl, eget fringilla elit. Ut nec est sapien. Aliquam dignissim velit sed nunc imperdiet cursus. Proin arcu diam, tempus ac vehicula a, dictum quis nibh. Maecenas vitae quam ac mi venenatis vulputate. Suspendisse fermentum suscipit eros, ac ultricies leo sagittis quis. Nunc sollicitudin lorem eget eros eleifend facilisis. Quisque bibendum sem at bibendum suscipit. Nam id tellus mi. Mauris vestibulum, eros ac ultrices lacinia, justo est faucibus ipsum, sed sollicitudin sapien odio sed est. In massa ipsum, bibendum quis lorem et, volutpat ultricies nisi. Maecenas scelerisque sodales ipsum a hendrerit.</p>

I have this JSFiddle to illustrate the issue. https://jsfiddle.net/96knodm6/

20条回答
人间绝色
2楼-- · 2018-12-31 02:36

Pros:
+ Cross browser (IE11, Edge, Chrome, Firefox, Safari, etc.)
+ Most natural looking

Cons:
- Adds lots of extra elements to the DOM

I wasn't satisfied with any of the workarounds I had seen. Most of them use line-clamp which is currently only supported in webkit. So I played around with it until I came up with a solution. This pure javascript solution should be compatible with IE10 and greater and all modern browsers. This is untested outside of the stackoverflow example space below.

I think this is a good solution. The one big caveat is that it creates a span for each word inside the container, which will impact layout performance, so your mileage may vary.

//This is designed to be run on page load, but if you wanted you could put all of this in a function and addEventListener and call it whenever the container is resized.
var $container = document.querySelector('.ellipses-container');

//optional - show the full text on hover with a simple title attribute
$container.title = $container.textContent.trim();

$container.textContent.trim().split(' ').some(function (word) {
  //create a span for each word and append it to the container
  var newWordSpan = document.createElement('span');
  newWordSpan.textContent = word;
  $container.appendChild(newWordSpan);
  
  if (newWordSpan.getBoundingClientRect().bottom > $container.getBoundingClientRect().bottom) {
    //it gets into this block for the first element that has part of itself below the bottom of the container
    //get the last visible element
    var containerChildNodes = $container.childNodes;
    var lastVisibleElement = containerChildNodes[containerChildNodes.length - 2];
    
    //replace this final span with the ellipsis character
    newWordSpan.textContent = '\u2026';
    
    //if the last visible word ended very near the end of the line the ellipsis will have wrapped to the next line, so we need to remove letters from the last visible word
    while (lastVisibleElement.textContent != "" && newWordSpan.getBoundingClientRect().bottom > $container.getBoundingClientRect().bottom) {
      lastVisibleElement.style.marginRight = 0;
      lastVisibleElement.textContent = lastVisibleElement.textContent.slice(0, -1);
    }
    
    //using .some() so that we can short circuit at this point and no more spans will be added
    return true;
  }
});
.multi-line-container {
  border: 1px solid lightgrey;
  padding: 4px;
  height: 150px;
  width: 300px;
}

.ellipses-container {
  display: inline-flex;
  flex-wrap: wrap;
  justify-content: flex-start;
  align-content: flex-start; /* optionally use align-content:stretch, the default, if you don't like the extra space at the bottom of the box if there's a half-line gap */
  overflow: hidden;
  position: relative;
}

.ellipses-container > span {
  flex: 0 0 auto;
  margin-right: .25em;
}

.text-body {
  display: none;
}
<div class="multi-line-container ellipses-container">
  <div class="text-body ellipses-text">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque luctus ut massa eget porttitor. Nulla a eros sit amet ex scelerisque iaculis nec vitae turpis. Sed pharetra tincidunt ante, in mollis turpis consectetur at. Praesent venenatis pulvinar lectus, at tincidunt nunc finibus non. Duis tortor lectus, elementum faucibus bibendum vitae, egestas bibendum ex. Maecenas vitae augue vitae dui condimentum imperdiet sit amet mattis quam. Duis eleifend scelerisque magna sed imperdiet. Mauris tempus rutrum metus, a ullamcorper erat fringilla a. Suspendisse potenti. Praesent et mi enim. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.
  </div>
</div>

查看更多
与风俱净
3楼-- · 2018-12-31 02:41

Try this Simple way. I have also jsfiddle link here.

Here is -webkit-line-clamp has an important role. The value of this property decides how much lines are visible.

CSS PART

h3{
      text-align: center;
      overflow: hidden;
      text-overflow: ellipsis;
      margin: 0px 30px;
      display: -webkit-box;
      -webkit-line-clamp: 3;
      -webkit-box-orient: vertical;
   }

HTML PART

<h3>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.</h3>
查看更多
登录 后发表回答