Schauen wir uns an, wie wir die CSS-Eigenschaft `text-shadow` verwenden können, um wirklich 3D-wirkenden Text zu erzeugen. Man denkt bei `text-shadow` vielleicht daran, dass man damit unscharfe, verlaufend wirkende Farben hinter Text anwenden kann, und das stimmt! Aber genau wie bei `box-shadow` kann man steuern, wie unscharf der Schatten ist, einschließlich der Möglichkeit, ihn ganz ohne Unschärfe zu lassen. Das, kombiniert mit der durch Kommas getrennten Übergabe mehrerer Schatten und deren Stapelung, ist der CSS-Trick, den wir hier anwenden werden.
Am Ende werden wir etwas haben, das so aussieht

Kurze Auffrischung zu text-shadow
Die Syntax sieht so aus
.el {
text-shadow: [x-offset] [y-offset] [blur] [color];
}
x-offset: Position auf der x-Achse. Ein positiver Wert verschiebt den Schatten nach rechts, ein negativer Wert nach links. (erforderlich)y-offset: Position auf der y-Achse. Ein positiver Wert verschiebt den Schatten nach unten, ein negativer Wert nach oben. (erforderlich)blur: Wie viel Unschärfe der Schatten haben soll. Je höher der Wert, desto weicher der Schatten. Der Standardwert ist 0px (keine Unschärfe). (optional)color: Die Farbe des Schattens. (erforderlich)
Der erste Schatten
Beginnen wir mit der Erstellung unseres Effekts, indem wir nur **einen** Schatten hinzufügen. Der Schatten wird 6px nach rechts und 6px nach unten verschoben.
:root {
--text: #5362F6; /* Blue */
--shadow: #E485F8; /* Pink */
}
.playful {
color: var(--text);
text-shadow: 6px 6px var(--shadow);
}

Tiefe mit mehr Schatten erzeugen
Wir haben im Moment nur einen flachen Schatten – noch ist nicht viel 3D daran. Wir können Tiefe erzeugen und den Schatten mit dem eigentlichen Text verbinden, indem wir dem Element weitere `text-shadow`-Instanzen hinzufügen. Das Ganze wird einfach durch Kommas getrennt. Beginnen wir damit, einen weiteren in der Mitte hinzuzufügen.
.playful {
color: var(--text);
text-shadow: 6px 6px var(--shadow),
3px 3px var(--shadow);
}

Das bringt uns schon weiter, aber wir müssen noch ein paar Schatten hinzufügen, damit es gut aussieht. Je mehr Schritte wir hinzufügen, desto detaillierter wird das Endergebnis. In diesem Beispiel beginnen wir bei 6px 6px und arbeiten uns in 0,25-px-Schritten nach unten, bis wir 0 erreicht haben.
.playful {
color: var(--text);
text-shadow:
6px 6px var(--shadow),
5.75px 5.75px var(--shadow),
5.5px 5.5px var(--shadow),
5.25px 5.25px var(--shadow),
5px 5px var(--shadow),
4.75px 4.75px var(--shadow),
4.5px 4.5px var(--shadow),
4.25px 4.25px var(--shadow),
4px 4px var(--shadow),
3.75px 3.75px var(--shadow),
3.5px 3.5px var(--shadow),
3.25px 3.25px var(--shadow),
3px 3px var(--shadow),
2.75px 2.75px var(--shadow),
2.5px 2.5px var(--shadow),
2.25px 2.25px var(--shadow),
2px 2px var(--shadow),
1.75px 1.75px var(--shadow),
1.5px 1.5px var(--shadow),
1.25px 1.25px var(--shadow),
1px 1px var(--shadow),
0.75px 0.75px var(--shadow),
0.5px 0.5px var(--shadow),
0.25px 0.25px var(--shadow);
}
Code-Vereinfachung mit Sass
Das Ergebnis mag gut aussehen, aber der Code ist im Moment ziemlich schwer zu lesen und zu bearbeiten. Wenn wir den Schatten größer machen wollen, müssten wir viel kopieren und einfügen, um das zu erreichen. Zum Beispiel würde eine Vergrößerung der Schatten auf 10px bedeuten, manuell 16 weitere Schatten hinzuzufügen.
Und da kommt SCSS ins Spiel. Wir können Funktionen verwenden, um die Generierung aller Schatten zu automatisieren.
@function textShadow($precision, $size, $color){
$value: null;
$offset: 0;
$length: $size * (1 / $precision) - 1;
@for $i from 0 through $length {
$offset: $offset + $precision;
$shadow: $offset + px $offset + px $color;
$value: append($value, $shadow, comma);
}
@return $value;
}
.playful {
color: #5362F6;
text-shadow: textShadow(0.25, 6, #E485F8);
}
Die Funktion `textShadow` nimmt drei verschiedene Argumente entgegen: die Präzision, die Größe und die Farbe des Schattens. Sie erstellt dann eine Schleife, bei der der Versatz um `$precision` (in diesem Fall 0,25px) erhöht wird, bis er die Gesamtgröße (in diesem Fall 6px) des Schattens erreicht.
Auf diese Weise können wir die Größe oder Präzision des Schattens leicht erhöhen. Um beispielsweise einen Schatten zu erstellen, der 10px groß ist und sich um 0,1px erhöht, müssten wir nur Folgendes in unserem Code ändern:
text-shadow: textShadow(0.1, 10, #E485F8);
Abwechselnde Farben
Wir wollen die Dinge ein wenig aufpeppen, indem wir abwechselnde Farben verwenden. Wir teilen den Text in einzelne Buchstaben auf, die in `span`-Elemente eingeschlossen sind (dies kann manuell oder automatisiert mit React oder JavaScript erfolgen). Die Ausgabe sieht dann so aus:
<p class="playful" aria-label="Wash your hands!">
<span aria-hidden="true">W</span><span aria-hidden="true">a</span><span aria-hidden="true">s</span><span aria-hidden="true">h</span> ...
</p>
Dann können wir den Selektor `:nth-child()` auf die `span`-Elemente anwenden, um die Farbe ihres Textes und Schattens zu ändern.
.playful span:nth-child(2n) {
color: #ED625C;
text-shadow: textShadow(0.25, 6, #F2A063);
}
Wenn wir das in reinem CSS gemacht hätten, würde es so aussehen:
.playful span {
color: var(--text);
text-shadow:
6px 6px var(--shadow),
5.75px 5.75px var(--shadow),
5.5px 5.5px var(--shadow),
5.25px 5.25px var(--shadow),
5px 5px var(--shadow),
4.75px 4.75px var(--shadow),
4.5px 4.5px var(--shadow),
4.25px 4.25px var(--shadow),
4px 4px var(--shadow),
3.75px 3.75px var(--shadow),
3.5px 3.5px var(--shadow),
3.25px 3.25px var(--shadow),
3px 3px var(--shadow),
2.75px 2.75px var(--shadow),
2.5px 2.5px var(--shadow),
2.25px 2.25px var(--shadow),
2px 2px var(--shadow),
1.75px 1.75px var(--shadow),
1.5px 1.5px var(--shadow),
1.25px 1.25px var(--shadow),
1px 1px var(--shadow),
0.75px 0.75px var(--shadow),
0.5px 0.5px var(--shadow),
0.25px 0.25px var(--shadow);
}
.playful span:nth-child(2n) {
--text: #ED625C;
--shadow: #F2A063;
}
Wir können das ein paar Mal mit anderen Farben und Indizes wiederholen, bis wir ein Muster erreicht haben, das uns gefällt.
Bonuspunkte: Animation hinzufügen
Mit denselben Prinzipien können wir den Text noch mehr zum Leben erwecken, indem wir Animationen hinzufügen. Zuerst fügen wir eine wiederholte Animation hinzu, die jeden `span` auf und ab bewegt.
.playful span {
color: #5362F6;
text-shadow: textShadow(0.25, 6, #E485F8);
position: relative;
animation: scatter 1.75s infinite;
}
Wir können dies noch weiter optimieren, indem wir die Media-Query `prefers-reduced-motion` verwenden. Auf diese Weise erhalten Leute, die keine Animation wünschen, diese auch nicht.
.playful span {
color: #5362F6;
text-shadow: textShadow(0.25, 6, #E485F8);
position: relative;
animation: scatter 1.75s infinite;
}
@media screen and (prefers-reduced-motion: reduce) {
animation: none;
}
Dann fügen wir in jedem `nth-child(n)` eine andere Animationsverzögerung hinzu.
.playful span:nth-child(2n) {
color: #ED625C;
text-shadow: textShadow(0.25, 6, #F2A063);
animation-delay: 0.3s;
}
beeinflusst dieser Trick die Ladezeit einer Website?
Die Ladezeit sollte sich nicht wesentlich beeinflussen lassen, aber die Verwendung dieses Effekts auf großen Textmengen kann das Rendering auf Mobilgeräten verlangsamen (Dutzende von Schatten sind wahrscheinlich nicht billig).
Schön! Ich schätze die zugängliche Behandlung hier.
Die Animation kann viel flüssiger sein, wenn man die `transform`-Eigenschaft animiert. `translate` funktioniert nicht bei Inline-Eigenschaften, daher habe ich die Wörter umschlossen und alles auf `display: inline-block` gesetzt. Ich weiß nicht, ob es dafür einen saubereren Weg gibt ... aber Wortumbrüche sind sowieso nützlich. Ich glaube, ich habe die gleiche Zugänglichkeit beibehalten, bin mir aber nicht zu 100% sicher.
https://codepen.io/jerome-toole/full/bGVwXqe
Vielen Dank, Kumpel, ich habe dieses CSS gerade auf meiner Hugo-Seite implementiert und es ist wirklich schön.
Dieser Trick funktioniert auf meiner Website, super!