Es ist kein Geheimnis, dass MDN ein neues Design ausgerollt zurück im März. Es ist wunderschön! Und es gibt einige süße CSS-y-Juwelen darin, die Spaß machen, sich anzusehen. Eines dieser Juwelen ist, wie Kartenkomponenten mit abgeschnittenem Text umgehen.
Ziemlich cool, ja? Ich möchte das gleich auseinander nehmen, aber ein paar Dinge ziehen mich wirklich in diesen Ansatz:
- Es ist ein Beispiel für das absichtliche Abschneiden von Inhalten. Wir haben das so bezeichnet CSS-Datenverlust an anderen Orten. Und während Datenverlust im Allgemeinen eine schlechte Sache ist, gefällt mir, wie es hier verwendet 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
, ein Thema, das erst kürzlich bei Eric Eggert aufkam von Locals geführtes seine Bedenken damit. Das Hauptargument dagegen ist, dass es keine Möglichkeit gibt, den Text wiederherzustellen, der beim Abschneiden abgeschnitten wird – Hilfstechnologien werden ihn ankündigen, aber sehende Benutzer haben keine Möglichkeit, ihn wiederherzustellen. Der MDN-Ansatz bietet in dieser Abteilung etwas mehr Kontrolle, da die Kürzung 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 grundlegende Stile hinzufügen, um die Dinge zu stützen.
Wieder nichts Besonderes. Unser Ziel ist es, den Inhalt beispielsweise nach der dritten Zeile abzuschneiden. Wir können a einstellen max-height
auf den Absatz und blenden Sie den Überlauf dafür aus:
.card p {
max-height: calc(4rem * var(--base)); /* Set a cut-off point for the content */
overflow: hidden; /* Cut off the content */
}
Whoa whoa, was ist damit los calc()
Sachen? Beachten Sie, dass ich a eingerichtet habe --base
Variable im Voraus, die als gemeinsamer Multiplikator verwendet werden kann. Ich benutze es, um die zu berechnen font-size
, line-height
, padding
für die Karte, und jetzt die max-height
des Absatzes. Ich finde es einfacher, mit konstanten Werten zu arbeiten, besonders wenn die Größe, die ich brauche, wirklich auf einer solchen Skala basiert. Mir ist aufgefallen, dass MDN ein ähnliches verwendet --base-line-height
Variable, wahrscheinlich für den gleichen Zweck.
Die dritte Textzeile ausblenden lassen? Es ist ein Klassiker linear-gradient()
auf dem Absatz :after
Pseudo-Element, das an der unteren rechten Ecke der Karte angeheftet ist. So können wir das 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 a anrufe --background
Variable, die auf denselben Wert für die Hintergrundfarbe eingestellt ist, der auf der verwendet wird .card
selbst. Auf diese Weise scheint der Text in den Hintergrund zu treten. Und ich habe festgestellt, dass ich den zweiten Farbstopp im Farbverlauf anpassen musste, da der Text nicht vollständig ausgeblendet wird, wenn der Farbverlauf zu 100 % überblendet wird. ich fand 80%
ein süßer Fleck für meine Augen sein.
Und ja, :after
braucht ein height
und width
dem „Vermischten Geschmack“. Seine height
ist wo das --base
Variablen kommen wieder ins Spiel, weil wir wollen, dass sie auf die des Absatzes skaliert werden line-height
um den Text mit der Höhe von zu überdecken :after
.
.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 an Höhe schien den Trick zu machen, aber MDN konnte es ohne es durchziehen, als ich einen Blick auf DevTools warf. Andererseits benutze ich nicht top
(oder inset-block-start
), um den Gradienten auch in diese Richtung zu versetzen. 🤷♂️
Nun p:after
absolut positioniert ist, müssen wir explizit die relative Positionierung für den Absatz deklarieren, der beibehalten werden soll :after
in seinem Fluss. Andernfalls, :after
vollständig aus dem Belegfluss herausgerissen und außerhalb der Karte landen würden. Dies wird zum vollständigen CSS für die .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, richtig? Nö! Der Dang-Gradient scheint einfach nicht an der richtigen Position zu sein.
Ich gebe zu, dass ich mir bei diesem einen Gedanken gemacht und DevTools auf MDN gestartet habe, um zu sehen, was zum Teufel mir entgangen ist. Oh ja, :after
muss als Blockelement dargestellt werden. Es ist klar wie der Tag, 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 alle zusammen!
Und ja, Aussehen hört sich so an, als würde VoiceOver den vollständigen Text respektieren. Andere Screenreader habe ich allerdings nicht getestet.
Mir ist auch aufgefallen, dass die Implementierung von MDN entfernt wird pointer-events
für p:after
. Wahrscheinlich eine gute Abwehrtaktik, um merkwürdiges Verhalten bei der Textauswahl zu verhindern. Ich habe es hinzugefügt und die Auswahl von Text fühlt sich etwas flüssiger an, zumindest in Safari, Firefox und Chrome.