[html] Applying an ellipsis to multiline text

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.

_x000D_
_x000D_
//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._x000D_
var $container = document.querySelector('.ellipses-container');_x000D_
_x000D_
//optional - show the full text on hover with a simple title attribute_x000D_
$container.title = $container.textContent.trim();_x000D_
_x000D_
$container.textContent.trim().split(' ').some(function (word) {_x000D_
  //create a span for each word and append it to the container_x000D_
  var newWordSpan = document.createElement('span');_x000D_
  newWordSpan.textContent = word;_x000D_
  $container.appendChild(newWordSpan);_x000D_
  _x000D_
  if (newWordSpan.getBoundingClientRect().bottom > $container.getBoundingClientRect().bottom) {_x000D_
    //it gets into this block for the first element that has part of itself below the bottom of the container_x000D_
    //get the last visible element_x000D_
    var containerChildNodes = $container.childNodes;_x000D_
    var lastVisibleElement = containerChildNodes[containerChildNodes.length - 2];_x000D_
    _x000D_
    //replace this final span with the ellipsis character_x000D_
    newWordSpan.textContent = '\u2026';_x000D_
    _x000D_
    //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_x000D_
    while (lastVisibleElement.textContent != "" && newWordSpan.getBoundingClientRect().bottom > $container.getBoundingClientRect().bottom) {_x000D_
      lastVisibleElement.style.marginRight = 0;_x000D_
      lastVisibleElement.textContent = lastVisibleElement.textContent.slice(0, -1);_x000D_
    }_x000D_
    _x000D_
    //using .some() so that we can short circuit at this point and no more spans will be added_x000D_
    return true;_x000D_
  }_x000D_
});
_x000D_
.multi-line-container {_x000D_
  border: 1px solid lightgrey;_x000D_
  padding: 4px;_x000D_
  height: 150px;_x000D_
  width: 300px;_x000D_
}_x000D_
_x000D_
.ellipses-container {_x000D_
  display: inline-flex;_x000D_
  flex-wrap: wrap;_x000D_
  justify-content: flex-start;_x000D_
  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 */_x000D_
  overflow: hidden;_x000D_
  position: relative;_x000D_
}_x000D_
_x000D_
.ellipses-container > span {_x000D_
  flex: 0 0 auto;_x000D_
  margin-right: .25em;_x000D_
}_x000D_
_x000D_
.text-body {_x000D_
  display: none;_x000D_
}
_x000D_
<div class="multi-line-container ellipses-container">_x000D_
  <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._x000D_
  </div>_x000D_
</div>
_x000D_
_x000D_
_x000D_

Examples related to html

Embed ruby within URL : Middleman Blog Please help me convert this script to a simple image slider Generating a list of pages (not posts) without the index file Why there is this "clear" class before footer? Is it possible to change the content HTML5 alert messages? Getting all files in directory with ajax DevTools failed to load SourceMap: Could not load content for chrome-extension How to set width of mat-table column in angular? How to open a link in new tab using angular? ERROR Error: Uncaught (in promise), Cannot match any routes. URL Segment

Examples related to css

need to add a class to an element Using Lato fonts in my css (@font-face) Please help me convert this script to a simple image slider Why there is this "clear" class before footer? How to set width of mat-table column in angular? Center content vertically on Vuetify bootstrap 4 file input doesn't show the file name Bootstrap 4: responsive sidebar menu to top navbar Stylesheet not loaded because of MIME-type Force flex item to span full row width

Examples related to ellipsis

What is the hamburger menu icon called and the three vertical dots icon called? Applying an ellipsis to multiline text How to have Ellipsis effect on Text CSS text-overflow: ellipsis; not working? Android, How to limit width of TextView (and add three dots at the end of text)? Why doesn't CSS ellipsis work in table cell? HTML text-overflow ellipsis detection With CSS, use "..." for overflowed block of multi-lines HTML - how can I show tooltip ONLY when ellipsis is activated Limit text length to n lines using CSS