Sie wünschen sich X Zeilen Text. Alles danach wird: anmutig abgeschnitten. Das ist „Zeilenbeschränkung“ und ein absolut legitimer Wunsch. Wenn Sie die Anzahl der Textzeilen genau kennen, können Sie stärkere und zuverlässigere Raster aus den Elementen erstellen, die diesen Text enthalten, und gleichzeitig eine symmetrische ästhetische Harmonie erreichen.
Dafür gibt es ein paar Möglichkeiten, keine davon ist spektakulär.
Falls diese Erklärung nicht klar war, stellen Sie sich vor, Sie haben HTML wie dieses
<div class="module">
<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.</p>
</div>
Und Sie möchten es auf genau drei Zeilen in einem Container begrenzen. So:
In all diesen Beispielen gehen wir von einem „Modul“ aus.
.module {
width: 250px;
overflow: hidden;
}
Der standardisierte Weg
Früher nannte ich das „der seltsame WebKit-Flexbox-Weg“, aber in einer besonders seltsamen Wendung beinhaltet die Spezifikation dies nun als Teil des Overflow-Moduls, inklusive der alten Flexbox. Und Firefox hat es genau so implementiert. Und mit Edge-gone-Chromium ist diese seltsame Technik viel nützlicher geworden statt weniger.
.line-clamp {
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
}
Trotz der seltsamen Syntax ist das großartig und genau das, was wir brauchen. Hier ist ein Spielplatz, um damit herumzuspielen
Um fair zu sein, es ist wirklich seltsam. Warum muss es eine Flexbox-Sache sein (die alte Version)? Ohne das funktioniert es nicht. Und es ist extrem fehleranfällig. Nehmen wir an, Sie möchten, dass das Modul (oder der Absatz) etwas Polsterung hat. Das können Sie nicht, denn die Polsterung würde zusätzliche Zeilen freilegen. Das bekommen wir mit halbfertigen, ursprünglich nicht standardisierten Eigenschaften.
Die Ausblendmethode
Der Kern dieser Technik ist einfach, die Höhe des Moduls auf vorhersagbare Weise festzulegen. Nehmen wir an, Sie setzen line-height auf 1.2em. Wenn wir drei Textzeilen anzeigen möchten, können wir einfach die Höhe des Containers auf 3.6em (1.2em × 3) setzen. Der versteckte Überlauf wird den Rest ausblenden.
Aber es kann etwas ungeschickt sein, den Text einfach so abzuschneiden. Idealerweise würden wir Ellipsen hinzufügen, aber wir können sie nicht zuverlässig positionieren. Stattdessen blenden wir den Text aus und erreichen so die gleiche Art der Kommunikation („da ist mehr…“).
Um die letzte Zeile auszublenden, erstellen wir eine Box (ein Pseudo-Element eignet sich hervorragend) und überlagern einen transparenten zu Hintergrundfarbe verlaufenden Farbverlauf. Ihn fast so breit wie der Container zu machen, ist am besten, falls die letzte Zeile kurz ist. Da wir die line-height kennen, können wir das Pseudo-Element genau eine Zeile hoch machen.
.fade {
position: relative;
height: 3.6em; /* exactly three lines */
}
.fade::after {
content: "";
text-align: right;
position: absolute;
bottom: 0;
right: 0;
width: 70%;
height: 1.2em;
background: linear-gradient(to right, rgba(255, 255, 255, 0), rgba(255, 255, 255, 1) 50%);
}
Der Opera Overflow Weg
Opera als eigene Rendering-Engine ist seit langem defekt. Ich lasse das nur aus historischen Gründen drin.
Wie WebKit hat Opera seine eigene Methode, dies zu handhaben. Sie wenden Ellipsen auf die gewünschte Zeile an. Natürlich tickt die Uhr für Presto (Operas Rendering-Engine vor Blink), daher ist das nicht besonders nützlich. Vielleicht kann es aber trotzdem eine zukünftige Implementierung beeinflussen.
.last-line {
height: 3.6em; /* exactly three lines */
text-overflow: -o-ellipsis-lastline;
}
Der Clamp.js Weg
Wo ein Wille ist, ist auch ein Weg (mit JavaScript). Ich glaube, das ist ein Sprichwort. Joseph J. Schmitt hat eine ausgezeichnete, bibliotheksfreie JavaScript-Lösung namens Clamp.js, um dies browserübergreifend zu realisieren.
var module = document.getElementById("clamp-this-module");
$clamp(module, {clamp: 3});
Stellen Sie sicher, dass Sie das Element mit dem Text direkt ansprechen. Ursprünglich habe ich versucht, die ID auf das Modul zu setzen, was in Chrome/Safari funktionierte, aber in Firefox fehlschlug. Das Setzen auf die <p>-Tags funktionierte in beiden (Thx Merri).
Die reine CSS-Methode mit verstecktem Überlauf und platzierten Ellipsen
Der Trick besteht darin, eine max-height festzulegen, die der maximalen Anzahl von Zeilen multipliziert mit der line-height entspricht.
html {
--lh: 1.4rem;
line-height: var(--lh);
}
.truncate-overflow {
--max-lines: 3;
position: relative;
max-height: calc(var(--lh) * var(--max-lines));
overflow: hidden;
padding-right: 1rem; /* space for ellipsis */
}
.truncate-overflow::before {
position: absolute;
content: "...";
inset-block-end: 0; /* "bottom" */
inset-inline-end: 0; /* "right" */
}
.truncate-overflow::after {
content: "";
position: absolute;
inset-inline-end: 0; /* "right" */
width: 1rem;
height: 1rem;
background: white;
}
Der Rest besteht darin, am Ende der Zeilen einen „…“-Ellipsen-Punkt zu platzieren, aber *nur*, wenn der Text die maximale Anzahl von Zeilen überschreitet.
Die Demos
Update: Weitere gute Wege!
- Es gibt eine außergewöhnlich clevere reine CSS-Methode dafür, die im Mobify-Blog veröffentlicht wurde Update: Link entfernt, toter Blog, Technik hier eingefügt.
- Vesa Piittinen hat eine alternative Methode zu Clamp.js erstellt.
„Im Gegensatz zu Clamp.js behält sie den gesamten Text innerhalb des begrenzten Elements und nutzttext-overflowfür die Magie.“ - FT Labs hat ebenfalls ein JavaScript-Plugin entwickelt, um die Aufgabe zu erledigen. Es ist gut, da Sie die Anzahl der Zeilen nicht angeben müssen, es passiert einfach, wenn der Text den Container überläuft, sodass die Designentscheidungen im CSS verbleiben.
- Succinct: „Ein winziges jQuery-Plugin zum Abschneiden von mehrzeiligem Text.“
Diese Beispiele wurden zum Haupt-Pen hinzugefügt.
Es gibt auch Shave von DollarShaveClub
Die Clamp.js-Methode funktionierte bei mir tatsächlich nicht (FF 20). Ich bin immer noch der Meinung, dass die von mir bevorzugte Methode die Farbverlaufsüberlagerung ist. Ein weiteres Element könnte dann über dem Pseudo-Element platziert werden, um weiter auf mehr Inhalt hinzuweisen (ein „Weiterlesen“-Link). Das heißt, ohne einige größere Hacks für IE suchen wir immer noch nach einer guten browserübergreifenden Methode.
Matt, ich sehe dasselbe bei FF 20.0 auf Mac.
Hier ist ein Screenshot für Interessierte: http://i.imgur.com/WJGNQmD.png
Okay, es scheint ein bekanntes Problem zu sein: https://github.com/josephschmitt/Clamp.js/issues/3
Sie können es in Aktion sehen, wenn FF20: http://codepen.io/jcummins/pen/nvEmf
Hier ist ein aktualisierter Screenshot: http://i.imgur.com/Ubv3NLl.png
Selectivizr?
Der Versuch, die elegante Kürzung zu erreichen, war ein Fluch meines Daseins, seit ich mit der Webentwicklung begonnen habe. Danke für die Hervorhebung dieser Funktion; ich werde sie auf jeden Fall nutzen.
Ich habe ein einfaches jQuery-Plugin implementiert, das es Ihnen ermöglicht, etwas Ähnliches und mehr zu erreichen.
Keine Liebe für text-overflow: ellipsis?
Es funktioniert nur, wenn auch white-space: nowrap aktiv ist.
text-overflow: ellipsis funktioniert jedoch nur bei der ersten und einzigen Textzeile.
Der Punkt des Artikels ist, was wir verwenden können, um einen Überlauf anzuzeigen, wenn Text auf mehreren Zeilen umbricht.
Sie können tatsächlich
white-space: preverwenden und es funktioniert für jede Zeile.Das bedeutet, Sie können etwas JavaScript schreiben, um ein oder zwei Zeilenumbrüche hinzuzufügen, und dann erhält die letzte Zeile Ellipsen.
Der schwierige Teil ist die effiziente Messung von Text.
Ich wusste nichts von der Überschneidung von pre mit overflow, Merri, danke für die Info.
Trotzdem erfordert diese Lösung JavaScript und ändert den Inhalt selbst.
Beim Kopieren und Einfügen von Text werden Zeilenumbrüche eingefügt.
Das ist für meinen üblichen Anwendungsfall nicht akzeptabel, aber andere Leute würden es nicht stören.
Das w3c zielt auf dieses Problem in seinem „CSS Overflow Module Level 3“-Arbeitsentwurf ab.
Basierend auf dieser *sehr* frühen Spezifikation können wir theoretisch den 3-Zeilen-Clamp wie folgt machen
.line-clamp {
overflow: fragments;
}
.line-clamp::nth-fragment(1){
max-lines: 3;
}
.line-clamp::nth-fragment(2){
display:none;
}
Zugegeben, es ist eine frühe Spezifikation, aber das hilft eigentlich nicht weiter. Wir können Text bereits nach n Zeilen abschneiden, unser Problem ist, die Ellipsen am Ende der gewünschten Zeilen zu platzieren.
Wir haben also unsere Fragmente und verstecken alle bis auf das erste. Aber was machen wir mit dem ersten Fragment?
Es scheint mir, dass die Spezifikation eher darauf abzielt, das gleiche Problem wie CSS Regions zu lösen. Aber was wir eigentlich brauchen, ist eine :overflowing-Pseudoklasse. Designer fragen danach seit, sagen wir, 1998...
Die Ausblendmethode hat einen kleinen Haken... was ist, wenn der Text genau in 3 Zeilen passt? In diesem Fall möchten Sie das Ende der dritten Zeile NICHT ausblenden, da kein weiterer Inhalt folgt. Sicherlich, wenn Sie wissen, dass der Text passt, würden Sie ihn nicht abschneiden wollen, aber wenn Sie es nicht wissen...
Ich mag die Farbverlaufsmethode auch (nach einer anständigen standardisierten Clamp-Methode natürlich). Ich glaube wirklich, Sie müssten `pointer-events: none;` auf dem Pseudo-Element setzen.
Da Clamp.js anscheinend einfach nicht funktioniert. Nach einiger Versuchs- und Irrtum-Arbeit scheint stattdessen dies zuverlässig browserübergreifend zu funktionieren
http://codepen.io/Merri/pen/Dsuim
Es bedarf weiterer Optimierungen, es muss die Datenzeichenkette nicht wirklich bearbeiten, wie sie es tut, und es könnte die Elemente einfach in der ersten Replace-Callback-Schleife erstellen.
Die Ausblendtechnik ähnelt dem, was Polygon Polygon verwendet.
Danke für den nützlichen Beitrag, Chris.
Die Jungs von FT Labs haben auch ftellipsis entwickelt, das dasselbe tut und in Nicht-Webkit-Browsern auf das Abschneiden von Text und die Positionierung eines Elements über dem Ende der überlaufenden Zeile zurückfällt.
Getestet. Wie Clamp.js scheint es nur in einem Webkit-Browser zu funktionieren.
Zu den Demos hinzugefügt, danke!
… und falschen Namen verwendet… Egal. Clamp.js funktioniert doch, Chris zielt nur auf das falsche Element in seinem Beispiel (die ID sollte im Absatz und nicht im Div sein).
Was mir an Clamp.js nicht gefällt, ist, wie es den ursprünglichen Text aus dem Element entfernt.
Eine weitere reine CSS-Methode, die bereits auf diesem Blog verlinkt wurde, finden Sie hier: http://www.mobify.com/blog/multiline-ellipsis-in-pure-css/
Als Webdesign-Neuling finde ich all diese kleinen Dinge verrückt. Sogar das Programmieren von Spielen ist weniger ein Kopfzerbrechen als Webdesign, ich war überrascht.
Genau das musste ich vor ein paar Tagen für meine Website tun, und die Lösung, die ich fand, war, einen Zeilenumbruch durchzuführen UND die Zeilen über PHP zu zählen. Ganz zu schweigen davon, ein Skript zu bekommen, das sicherstellt, dass HTML-Tags nicht als Wörter gezählt werden.
Also, wann wird einer von euch eine völlig neue Art entwickeln, Websites zu erstellen, eine, die logisch, browserübergreifend konsistent ist und grundlegende Dinge schmerzfrei erledigt? Ich schicke Ihnen 100 $ auf Ihr PayPal, vielleicht sogar mehr.
WOW! Mir gefällt Clamp.js, es scheint nur in einem -webkit- Browser zu funktionieren.
Einige interessante Beispiele, wie man dies erreicht. Als wir dies in der Vergangenheit getan haben, haben wir PHP verwendet, um dies zu erreichen. Mit etwas Glück können wir das bald abschaffen!
Ich verstehe nicht, wie „The Fade Out Way“ überhaupt funktionieren kann, da man nicht die gleiche Schriftgröße über Browser hinweg garantieren kann.
Selbst wenn Sie `line-height` und `font-size` festlegen, wird der Text immer noch an verschiedenen Stellen überlaufen. Je nach Browser stoppt er vielleicht kurz vor dem Ende des Containers, aber bei anderen Browsern kann die letzte Zeile vom Container halbiert werden.
Ich habe kürzlich online nach einer Lösung für dieses Problem recherchiert und bin auf ein jQuery-Plugin namens dotdotdot gestoßen. Offensichtlich ist es keine reine CSS-Lösung, aber CSS steuert seine Anwendung effektiv, da die Bibliothek den Textcontainer misst und nur auf überlaufende Inhalte angewendet wird.
Eines der coolsten Features von ‚dotdotdot‘ (und der Hauptgrund, warum ich es anderen Lösungen vorzog) ist die Möglichkeit, sicherzustellen, dass bestimmter Inhalt sichtbar bleibt oder benutzerdefinierter Inhalt hinzugefügt wird, wenn Ellipsen benötigt werden. In meinem speziellen Fall schnitt ich Produktbeschreibungen auf einer E-Commerce-Website ab und musste sicherstellen, dass die Produkt-ID am Ende der Beschreibung sichtbar blieb, auch wenn Ellipsen vorhanden waren.
Die Bibliothek hat mir bisher sehr gut gedient und ich empfehle sie wärmstens. Ich habe noch keine „abhängigkeitsfreie“ Version (kein jQuery) benötigt, aber wenn doch, werde ich wahrscheinlich den Entwickler kontaktieren und um einen Vanilla-JS-Port bitten oder es selbst machen.
Schauen Sie sich https://gist.github.com/depoulo/5832073 an
Nur CSS, berücksichtigt den Fall, dass Sie Text haben, der so lang ist wie die Anzahl der Zeilen, die Sie anzeigen möchten (dann möchten Sie keine Punkte), und Sie können leicht einen -webkit-line-clamp-Schalter hineinnehmen.
Der Opera Overflow Way funktioniert nicht. Ich vermute, weil Opera die Engine selbst ändert.
Mir gefällt Clamp.js, es scheint nur in einem -webkit- Browser zu funktionieren.