Multi-Line Truncation mit reinem CSS

Avatar of Chris Coyier
Chris Coyier am

DigitalOcean bietet Cloud-Produkte für jede Phase Ihrer Reise. Starten Sie mit 200 $ kostenlosem Guthaben!

Der Trick in diesem Artikel ist immer noch ziemlich nett und clever, aber es gibt einen jetzt standardisierten Weg, dies zu tun, der wahrscheinlich Ihre beste Wahl ist.

Das Abschneiden einer einzigen Zeile Text, wenn es recht einfach ist. Das Abschneiden mehrerer Zeilen ist etwas schwieriger. Die Verwendung von reinem CSS (ohne JavaScript oder serverseitige Tricks) ist schön wegen der Einfachheit. Es ist in letzter Zeit etwas einfacher geworden, da Firefox (seit Version 68) die extrem seltsame -webkit-line-clamp Suppenmethode unterstützt, was die Browserunterstützung dafür ziemlich gut macht.

Es gibt jedoch noch einen anderen Weg, der sehr clever ist und den ich als echten CSS-Trick bezeichnen würde. Wir haben es versäumt, ihn in unserem kanonischen Beitrag über Line-Clamping richtig zu behandeln, daher werde ich ihn hier behandeln und dann zu diesem Beitrag hinzufügen. Ich habe diesen Trick zuerst im inzwischen eingestellten Mobify-Blog gesehen und kürzlich von Natalia Onischuk auf HackingUI behandeln lassen.

Der Trick nutzt die Zeilenhöhe zur Messung

Hier ist ein großer Teil des Tricks. Stellen Sie sich vor, ein Element hat eine line-height von 1.4rem und Sie möchten sicherstellen, dass es nur maximal drei Zeilen Text anzeigt. Wenn Sie die max-height auf 1.4rem * 3 setzen, haben Sie es geschafft!

Ich bin kein großer Fan von vereinheitlichter line-height, aber leider ist sie hier für die Berechnungen notwendig. Ich bin auch kein großer Fan davon, sie ständig auf Elementen zu setzen, also definieren wir eine Variable, die wir später verwenden können, und setzen dann eine globale line-height.

html {
  --lh: 1.4rem;
  line-height: var(--lh);
}

Setzen Sie diese maximale Höhe

Das Abschneiden geschieht genau so

.truncate-overflow {
  --max-lines: 3;
  max-height: calc(var(--lh) * var(--max-lines));
  overflow: hidden;
}

Sie könnten es tatsächlich so lassen. Das mag ausreichen, wenn Sie sich nicht um die Ellipse kümmern.

Der Rest des Tricks kommt ins Spiel, wenn Sie dieses Ellipsen-Zeug anzeigen möchten

Eine Ellipse („…“) zeigt an, dass Text abgeschnitten wurde und länger ist, als angezeigt wird. Die Verwendung ist wahrscheinlich eine gute Praxis, wenn Text abgeschnitten wird, damit der Inhalt nicht abrupt und unbeholfen endet. (Nun, der Inhalt selbst mag sowieso unbeholfen sein, aber hey, Sie haben es versucht.)

Wenn Sie position: relative auf das Element setzen, können Sie die Ellipse absolut in der unteren rechten Ecke positionieren.

.truncate-overflow::before {
  content: "...";
  position: absolute;
  bottom: 0;
  right: 0;
}

Ich war sehr versucht, anstatt unten zu setzen, oben zu setzen und top: calc(var(--lh) * (var(--max-lines) - 1)) zu verwenden. Mein Gedanke war, dass man die Ellipse genauso gut an der genauen Stelle platzieren könnte, an der sie benötigt wird. Wenn der Text zu kurz ist, wird der verborgene Überlauf ihn abschneiden. Das Problem dabei ist, dass es das Problem der „genau maximalen Zeilen“ nicht löst. Die Ellipse wird angezeigt, wenn der Text dem Maximum entspricht – nicht nur, wenn er diesen Platz überschreitet.

Wir müssen raffinierter vorgehen!

Beachten Sie, dass dieses „Setzen von Dingen unten rechts“ ziemlich spezifisch für Sprachen von links nach rechts ist. Ich werde die Demo mit CSS-Logik-Eigenschaften wie inset-inline-end anstelle von right erstellen, in der Hoffnung, sie für verschiedene Sprachen und Ablaufmuster freundlicher zu gestalten.

Eine weitere Einschränkung ist, dass sich die Ellipse aufgrund ihrer absoluten Positionierung nicht an das letzte Wort anhängt. Das werden wir auch nicht beheben.

Lassen Sie uns die Ellipse abdecken, wenn der Text zu kurz ist

Dies ist der zweite Teil des Tricks. Wenn wir die absolute Positionierung immer am unteren/rechten Ende des Textes vornehmen, ist das in Ordnung. Aber wenn der Text genau dem Wert von --max-lines entspricht oder kleiner ist, wollen wir ihn ausblenden.

Der Trick dabei ist, eine kleine Box zu erstellen, die den gleichen Hintergrund hat wie das, was dahinter liegt, und sie über die Ellipse zu legen, um sie abzudecken. Das können wir mit dem anderen Pseudo-Element tun

.truncate-overflow::after {
  content: "";
  position: absolute;
  right: 0; /* note: not using bottom */
  width: 1rem;
  height: 1rem;
  background: white;
}

Ein weiterer Trick, den wir hier anwenden, ist das Nicht-Setzen einer Bottom-Eigenschaft (inset-block-end). Dies platziert die Box am Ende des Inhalts und nicht am Ende des relativen Elternteils, was sehr nützlich ist.

Ich werde die Boxen rot färben, damit Sie sie in diesen drei verschiedenen Beispielen sehen können

Das obere Beispiel hat mehr als drei Zeilen, daher sehen wir die Ellipse. Das zweite Beispiel hat nur zwei Zeilen, daher zeigt die rote Box, dass die Ellipse abgedeckt wird (aber stellen Sie sich eine weiße Box vor). Das letzte Beispiel zeigt, dass dieses System auch dann funktioniert, wenn der Inhalt genau dem Wert von --max-lines entspricht.

Demo

Ich habe wollte hier CSS-Logik-Eigenschaften verwenden, da die Browserunterstützung ziemlich gut geworden ist. Wenn Sie eine Version von IE unterstützen, müssen Sie bottom und right verwenden.

Diese Browserunterstützungsdaten stammen von Caniuse, wo Sie weitere Details finden. Eine Zahl gibt an, dass der Browser die Funktion ab dieser Version unterstützt.

Desktop

ChromeFirefoxIEEdgeSafari
8966Nein8915

Mobil / Tablet

Android ChromeAndroid FirefoxAndroidiOS Safari
12712712715.0-15.1

Barrierefreiheit-Bedenken

Joseph Scherben schrieb und erwähnte

Wenn die Elemente interaktive Elemente enthalten und der Überlauf versteckt ist (nicht scrollbar), wären diese Elemente fokussierbar, aber nicht auf der Website sichtbar. Dies könnte dazu führen, dass Benutzer mit Tastatur/assistiven Geräten ihren Platz im versteckten abgeschnittenen Inhalt verlieren.