Truncating Multiple Line Text

Wird wieder einmal benötigt wenn, auf einer Webseite der Text zu lange ist und es dann einen „mehr lesen“ Knopp geben soll. Fällt son bisschen in die Kategorie, „Dinge die die Welt nicht braucht“ ….

Aber na ja, manchmal gibt es Kunden die das benötigten und das hier ist der Recherche Ergebnis, so als Gedankenstütze, wenn ich das in 10min nicht mehr brauch und daher getrost vergessen kann.

Über die normale CSS Eigenschaft text-flow, für Einzeiler bin ich dann über kurz oder lang bei Css-tricks.com gelandet und habe da die für mich neue CSS Eigenschaft „line-clamp“ kennengelernt. Allerdings soll es noch einen Button am Ende geben, mit dem man das ganze öffnen und schliessen kann, das verlinkte JS war leider schon 10 Jahre alt… Schreckt erstmal ab.
Zudem soll dann natürlich auch noch eine kleine Animation beim öffnen und schliessen erfolgen.. da bin ich dann bei Derek Morash und seinem großartigen Artikel CSS line-clamp animation gelandet, von Mai 2023 🙂

Wirklich sehr schöner Artikel, direkt mit CodePen Beispiel: https://codepen.io/derekmorash/pen/abRjbpp

Und für den Fall das es mal offline gehen sollte, hier eine Kopie des Codes

HTML:
<div class="truncate truncate--line-clamped">
  <div class="truncate__inner">
    <h2>Click to expand</h2>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin ac magna tellus. Curabitur sed faucibus leo. Vivamus id elit nec nisi ultrices rutrum. Sed ornare metus sit amet arcu pulvinar feugiat. Phasellus eleifend, dolor vitae malesuada dignissim, diam ligula semper purus, id pulvinar magna nibh nec neque. Ut auctor sodales dictum. Cras erat tortor, vestibulum et porttitor vitae, consequat et erat. Nullam ullamcorper tempor leo in fermentum. Curabitur ultrices tempus pulvinar. Proin a finibus odio. Pellentesque nec urna id ex facilisis dictum. Proin elementum cursus dolor, in molestie sem fermentum eget.</p>

    <p>In rutrum id eros sed tincidunt. Vivamus lobortis orci id orci elementum, eget molestie ante varius. Pellentesque imperdiet accumsan ipsum, vitae auctor lacus. Praesent sit amet imperdiet neque. Integer in orci ligula. Nulla finibus interdum sapien tincidunt vestibulum. Cras id risus eu nisl scelerisque faucibus. Donec tellus nibh, convallis eu nisi a, tempus sollicitudin elit. Cras lorem mauris, ullamcorper ac arcu a, sodales accumsan ex. Aliquam luctus lacinia nisi, id tincidunt tortor aliquam vestibulum. Fusce faucibus, felis id consectetur tempor, felis nunc bibendum nunc, sit amet porttitor erat ex quis tortor. Nulla mattis eros interdum dictum aliquet.</p>

    <p>Nunc at nisi ac dolor egestas tempus. Aenean ornare nibh risus. Nulla tristique eu tellus sed interdum. Duis eu ligula sed orci venenatis elementum. Nullam ullamcorper tellus a ultrices sollicitudin. Maecenas lacinia augue velit, a sodales libero feugiat sed. Sed mauris nisl, dignissim at placerat sed, aliquet vel dolor. Aliquam erat volutpat.</p>
  </div>
</div>
CSS:
*, :after, :before {
  box-sizing: border-box;
}

.truncate {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  max-height: var(--truncate-height, auto);
  max-width: 550px;
  margin: 0 auto;
  overflow: hidden;
  transition: max-height 0.3s ease;
}

.truncate--line-clamped {
  -webkit-line-clamp: 3;
}

.truncate--expanded {
  max-height: var(--truncate-height-expanded, auto);
}


JS:
const truncateEl = document.querySelector('.truncate');
const truncateInnerEl = document.querySelector('.truncate__inner');
const truncateRect = truncateEl.getBoundingClientRect();
let truncateInnerRect = truncateInnerEl.getBoundingClientRect();

truncateEl.style.setProperty("--truncate-height", `${truncateRect.height}px`);

truncateEl.addEventListener('click', () => {
  if (truncateEl.classList.contains('truncate--expanded')) {
    close();
  } else {
    open();
  }
});

function open() {
  truncateEl.classList.remove('truncate--line-clamped');
  window.requestAnimationFrame(() => {
    truncateInnerRect = truncateInnerEl.getBoundingClientRect();
    truncateEl.style.setProperty("--truncate-height-expanded", `${truncateInnerRect.height}px`);
    truncateEl.classList.add('truncate--expanded');
  });
}

function close() {
  truncateEl.classList.remove('truncate--expanded');
  setTimeout(() => {
    truncateEl.classList.add('truncate--line-clamped');
  }, 300);
}