Es ist kein Geheimnis, dass MDN im März ein neues Design eingeführt hat. Es ist großartig! Und es gibt einige süße CSS-Perlen darin, die Spaß machen anzusehen. Eines dieser Juwelen ist, wie Kartenkomponenten abgeschnittenen Text verarbeiten.

Ziemlich cool, oder? Ich möchte das gleich auseinandernehmen, aber ein paar Dinge ziehen mich wirklich zu diesem Ansatz hin.
- Es ist ein Beispiel für absichtliches Abschneiden von Inhalten. Wir haben dies an anderer Stelle als CSS-Datenverlust bezeichnet. Und obwohl Datenverlust im Allgemeinen eine schlechte Sache ist, gefällt mir, wie er hier eingesetzt wird, da Auszüge als Teaser für den vollständigen Inhalt gedacht sind.
- Dies unterscheidet sich vom Abschneiden von Text mit
text-overflow: ellipsis, einem Thema, das kürzlich aufkam, als Eric Eggert Bedenken dazu äußerte. Das Hauptargument dagegen ist, dass es keine Möglichkeit gibt, den abgeschnittenen Text wiederherzustellen – assistierende Technologien kündigen ihn an, aber sehende Benutzer haben keine Möglichkeit, ihn wiederherzustellen. MDNs Ansatz bietet in diesem Bereich etwas mehr Kontrolle, da die Beschneidung lediglich visuell ist.
Also, wie hat MDN das gemacht? Nichts Besonderes, was das HTML angeht, nur ein Container mit einem Absatz.
<div class="card">
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Inventore consectetur temporibus quae aliquam nobis nam accusantium, minima quam iste magnam autem neque laborum nulla esse cupiditate modi impedit sapiente vero?</p>
</div>
Wir können ein paar Basistyle hinzufügen, um die Dinge zu festigen.
Wieder nichts Besonderes. Unser Ziel ist es, den Inhalt nach zum Beispiel der dritten Zeile abzuschneiden. Wir können dem Absatz eine max-height geben und den Überlauf dafür ausblenden.
.card p {
max-height: calc(4rem * var(--base)); /* Set a cut-off point for the content */
overflow: hidden; /* Cut off the content */
}
Halt halt, was ist mit diesem calc() Kram? Beachten Sie, dass ich oben eine --base Variable eingerichtet habe, die als gemeinsamer Multiplikator verwendet werden kann. Ich verwende sie, um die font-size, line-height, padding für die Karte und jetzt die max-height des Absatzes zu berechnen. Ich finde es einfacher, mit konstanten Werten zu arbeiten, insbesondere wenn die benötigte Größe wirklich auf Skalierung basiert, wie hier. Ich habe bemerkt, dass MDN eine ähnliche --base-line-height Variable verwendet, wahrscheinlich für den gleichen Zweck.
Die dritte Textzeile ausblenden lassen? Das ist ein klassischer linear-gradient() auf dem :after Pseudo-Element des Absatzes, das unten rechts an die Karte angepinnt ist. Also, das können wir so einrichten.
.card p:after {
content: ""; /* Needed to render the pseudo */
background-image: linear-gradient(to right, transparent, var(--background) 80%);
position: absolute;
inset-inline-end: 0; /* Logical property equivalent to `right: 0` */
}
Beachten Sie, dass ich eine --background Variable aufrufe, die auf denselben Hintergrundfarbwert gesetzt ist, der auch auf dem .card selbst verwendet wird. So scheint der Text in den Hintergrund zu verblassen. Und ich habe festgestellt, dass ich den zweiten Farbstop im Gradienten anpassen musste, da der Text nicht vollständig verborgen ist, wenn der Gradient bis zu 100 % reicht. Ich fand 80% als einen guten Sweet Spot für meine Augen.
Und ja, :after benötigt eine height und width. Die height ist es, wo die --base Variablen wieder ins Spiel kommen, denn wir wollen, dass sie an die line-height des Absatzes angepasst wird, um den Text mit der Höhe von :after abzudecken.
.card p:after {
/* same as before */
height: calc(1rem * var(--base) + 1px);
width: 100%; /* relative to the .card container */
}
Das Hinzufügen eines zusätzlichen Pixels Höhe schien den Trick zu tun, aber MDN konnte es ohne hinbekommen, als ich in DevTools nachgeschaut habe. Aber ich verwende auch top (oder inset-block-start) nicht, um den Gradienten in diese Richtung zu versetzen. 🤷♂️
Da p:after absolut positioniert ist, müssen wir dem Absatz explizit eine relative Positionierung erklären, um :after in seinem Fluss zu halten. Andernfalls würde :after vollständig aus dem Dokumentfluss gerissen und außerhalb der Karte landen. Dies wird zum vollständigen CSS für den .card Absatz.
.card p {
max-height: calc(4rem * var(--base)); /* Set a cut-off point for the content */
overflow: hidden; /* Cut off the content */
position: relative; /* needed for :after */
}
Wir sind fertig, oder? Nein! Der verdammte Gradient scheint einfach nicht an der richtigen Position zu sein.
Ich gebe zu, ich habe mich da vertan und MDN in DevTools aufgerufen, um zu sehen, was ich übersehen hatte. Oh ja, :after muss als Blockelement angezeigt werden. Es ist offensichtlich, wenn man einen roten Rand hinzufügt.🤦♂️
.card p:after {
content: "";
background: linear-gradient(to right, transparent, var(--background) 80%);
display: block;
height: calc(1rem * var(--base) + 1px);
inset-block-end: 0;
position: absolute;
width: 100%;
}
Jetzt alles zusammen!
Und ja, sieht klingt so, als ob VoiceOver den vollständigen Text respektiert. Ich habe jedoch keine anderen Screenreader getestet.

Ich habe auch bemerkt, dass MDNs Implementierung pointer-events von p:after entfernt. Wahrscheinlich eine gute defensive Taktik, um seltsame Verhaltensweisen beim Auswählen von Text zu verhindern. Ich habe es hinzugefügt und das Auswählen von Text fühlt sich ein wenig reibungsloser an, zumindest in Safari, Firefox und Chrome.
Es scheint etwas albern zu sein, ausschließlich
lch()in den Beispielen zu verwenden, wenn zum Zeitpunkt des Schreibens nur Safari es unterstützt. Ein Fallback wäre nett gewesen, da alle Beispiele für mich kaputt aussahen.Aber ansonsten ein cooler Artikel :)
Super wahr. Es ist wirklich ich, der versucht, mich mit der Syntax vertraut zu machen, aber lass uns stattdessen etwas hsl() hineinbringen.
Hier ist meine Idee mit Maske :)
Demo: https://codepen.io/t_afif/pen/jOzamEB
Der Bonus bei Masken ist, dass Sie sich nicht um den Hintergrund kümmern müssen, da Sie echte Transparenz haben werden.
Verdammt, das ist schön!
Gibt es eine leichte Möglichkeit zu erkennen, ob Text überläuft, und Techniken wie diese bedingt anzuwenden? Andernfalls kann das Ausblenden auch bei einem kurzen Absatz erfolgen, der sonst gut passen würde. Einer der Gründe für die Verwendung von
overflow: ellipsisist, diese Überlauferkennung kostenlos zu erhalten.Ich wünschte wirklich, wir hätten einen Selektor dafür:
::overflow-markToller Artikel wie immer, aber er sollte besser "Dinge, die man niemals tun sollte, auch wenn man kann" heißen. :)
Der Punkt von Overflow-Ellipsen ist das Verbergen von Text, der durch Ansichtsbeschränkungen ohne Mittel nicht sichtbar ist. Es hilft, Text effektiver darzustellen und natürlich auszusehen (wie jedes Überlaufverbergen). Es verbirgt Inhalte nicht vor denen, die Zugriff auf die Inhalte wünschen, da die Engine Ihr DOM nicht verändert.
Die vorgeschlagene Lösung verlangsamt nur das Rendern durch sinnlose Arbeit. Deshalb sind moderne Websites so dumm. Keine Inhalte, 72pt Schriftart, 4K-Hintergrund, zufällige Service-Worker, zufällige Service-Worker von zufälligen Domainnamen (hallo Google) und nette "Ellipsen".
PS: Keine Beleidigung, ich bin wahrscheinlich zu altmodisch und beschwere mich ständig über kaputte Dinge oder Dinge, die einfach sein sollten. Und sie waren es und funktionierten perfekt, bevor "UX"-Experten anfingen, jedes Pixel auf meinem Bildschirm auf jedem Betriebssystem zu verhunzen.
Das könnte man sicherlich unter so etwas einordnen. Ich bin generell zögerlich, etwas abzuschreiben, da ständig neue Anwendungsfälle und Szenarien auftauchen. Und vielleicht kommt dieser Effekt woanders nützlich. Persönlich finde ich diesen Ansatz interessant, weil er einige der Bedenken aufgreift, die Leute mit
text-overflow: ellipsishaben.Kann Weber etwas über die Idee dieses Basis-Multiplikators in CSS sagen?
Habe das schon vor langer Zeit gemacht
Ich denke, die Notwendigkeit, display:block; zu setzen, ist es wert, erklärt zu werden. Es schien mir anfangs sehr seltsam, da absolut positionierte Elemente standardmäßig ziemlich so funktionieren, als wären sie block (können z. B. größenverändert werden) und ich musste dies in ähnlichen Fällen nie tun.
Das Problem ist, dass
:afternicht horizontal positioniert ist, sondern seine Position aus dem Textfluss beibehält. Wenn Sie es aufdisplay:block;setzen, bricht es natürlich aus dem Textfluss aus in eine eigene Zeile und wird links horizontal positioniert.Sie stoßen nicht auf dieses Problem, wenn Sie alte
right:0; bottom:0;positionieren. Alternativ zudisplay:block;(und moderner alsright:0;oderleft:0;) könnten Sieinset-inline-end:0;verwenden, was wahrscheinlich intuitiver ist.Das MDN-Beispiel sieht gut aus.
Bei Verwendung des Brave-Browsers 1.42.88 (der Chromium 104.0… verwendet) funktionieren die Effekte nicht.