Eine grundlegende Übersicht darüber, wie Sie Animationen mit geteilten Buchstaben und Wörtern erstellen.
In diesem Beitrag möchte ich einige Ideen für die Lösung von Animationen und Interaktionen mit geteiltem Text für das Web vorstellen, die minimal, barrierefrei und browserübergreifend funktionieren. Demo ansehen
Wenn du lieber ein Video ansehen möchtest, findest du hier eine YouTube-Version dieses Beitrags:
Übersicht
Split-Textanimationen können beeindruckend sein. In diesem Beitrag werden wir nur an der Oberfläche des Animationspotenzials kratzen, aber er bietet eine Grundlage, auf der Sie aufbauen können. Das Ziel ist es, die Animation progressiv zu gestalten. Der Text sollte standardmäßig lesbar sein und die Animation sollte darauf aufbauen. Bewegungseffekte für geteilten Text können extravagant und potenziell störend sein. Daher werden HTML-Elemente nur manipuliert oder Bewegungsstile nur angewendet, wenn der Nutzer mit Bewegung einverstanden ist.
Hier ist eine allgemeine Übersicht über den Workflow und die Ergebnisse:
- Bereiten Sie bedingte Variablen für CSS und JS vor, die auf reduzierte Bewegungen reagieren.
- Vorbereiten von Dienstprogrammen zum Aufteilen von Text in JavaScript.
- Die bedingten Anweisungen und Dienstprogramme beim Seitenaufbau orchestrieren.
- CSS-Übergänge und ‑Animationen für Buchstaben und Wörter schreiben (der coole Teil!).
Hier ist eine Vorschau der bedingten Ergebnisse, die wir anstreben:

Wenn ein Nutzer reduzierte Bewegungen bevorzugt, lassen wir das HTML-Dokument unverändert und verzichten auf Animationen. Wenn die Bewegung in Ordnung ist, wird das Video in einzelne Abschnitte unterteilt. Hier sehen Sie eine Vorschau des HTML-Codes, nachdem der Text durch JavaScript in Buchstaben aufgeteilt wurde.

Bewegungsbedingungen vorbereiten
Die praktische Media-Anfrage available @media
(prefers-reduced-motion: reduce)
wird in diesem Projekt aus CSS und JavaScript verwendet. Diese Media-Anfrage ist unsere primäre Bedingung dafür, ob Text aufgeteilt werden soll oder nicht. Die CSS-Media-Query wird verwendet, um Übergänge und Animationen zurückzuhalten, während die JavaScript-Media-Query verwendet wird, um die HTML-Manipulation zurückzuhalten.
Bedingung für das Preisvergleichsportal vorbereiten
Ich habe PostCSS verwendet, um die Syntax von Media Queries Level 5 zu aktivieren. Damit kann ich einen booleschen Wert für eine Media Query in einer Variablen speichern:
@custom-media --motionOK (prefers-reduced-motion: no-preference);
JS-Bedingung vorbereiten
In JavaScript bietet der Browser eine Möglichkeit, Media-Queries zu prüfen. Ich habe Destrukturierung verwendet, um das boolesche Ergebnis aus der Media-Query-Prüfung zu extrahieren und umzubenennen:
const {matches:motionOK} = window.matchMedia(
'(prefers-reduced-motion: no-preference)'
)
Ich kann dann auf motionOK
testen und das Dokument nur ändern, wenn der Nutzer nicht darum gebeten hat, die Bewegung zu reduzieren.
if (motionOK) {
// document split manipulations
}
Ich kann denselben Wert mit PostCSS prüfen, um die @nest
-Syntax aus Nesting Draft 1 zu aktivieren. So kann ich die gesamte Logik für die Animation und die Stilvorgaben für das übergeordnete Element und die untergeordneten Elemente an einem Ort speichern:
letter-animation {
@media (--motionOK) {
/* animation styles */
}
}
Mit der benutzerdefinierten PostCSS-Eigenschaft und einem booleschen JavaScript-Wert können wir den Effekt jetzt bedingt aktualisieren. Das führt uns zum nächsten Abschnitt, in dem ich das JavaScript zum Umwandeln von Strings in Elemente aufschlüsseln werde.
Text aufteilen
Textbuchstaben, Wörter, Zeilen usw. können nicht einzeln mit CSS oder JS animiert werden. Um den Effekt zu erzielen, benötigen wir Kästen. Wenn wir jeden Buchstaben animieren möchten, muss jeder Buchstabe ein Element sein. Wenn wir jedes Wort animieren möchten, muss jedes Wort ein Element sein.
- JavaScript-Hilfsfunktionen zum Aufteilen von Strings in Elemente erstellen
- Verwendung dieser Dienstprogramme koordinieren
Dienstfunktion zum Aufteilen von Buchstaben
Eine gute Möglichkeit, damit zu beginnen, ist eine Funktion, die einen String entgegennimmt und jeden Buchstaben in einem Array zurückgibt.
export const byLetter = text =>
[...text].map(span)
Die Spread-Syntax aus ES6 hat uns dabei sehr geholfen.
Dienstfunktion zum Aufteilen von Wörtern
Ähnlich wie beim Aufteilen von Buchstaben wird bei dieser Funktion ein String verwendet und jedes Wort in einem Array zurückgegeben.
export const byWord = text =>
text.split(' ').map(span)
Mit der Methode split()
für JavaScript-Strings können wir angeben, an welchen Zeichen geschnitten werden soll.
Ich habe ein Leerzeichen eingefügt, um Wörter zu trennen.
Boxen als Dienstfunktion
Für den Effekt sind Kästchen für jeden Buchstaben erforderlich. In den Funktionen sehen wir, dass map()
mit einer span()
-Funktion aufgerufen wird. Hier ist die Funktion span()
.
const span = (text, index) => {
const node = document.createElement('span')
node.textContent = text
node.style.setProperty('--index', index)
return node
}
Wichtig: Eine benutzerdefinierte Eigenschaft namens --index
wird mit der Arrayposition festgelegt. Die Kästchen für die Buchstabenanimationen sind zwar gut, aber ein Index, der in CSS verwendet werden kann, ist eine scheinbar kleine Ergänzung mit großer Wirkung.
Am auffälligsten ist dabei die Staffelung.
Wir können --index
verwenden, um Animationen für ein gestaffeltes Erscheinungsbild zu versetzen.
Fazit zu Dienstprogrammen
Das Modul splitting.js
in der Übersicht:
const span = (text, index) => {
const node = document.createElement('span')
node.textContent = text
node.style.setProperty('--index', index)
return node
}
export const byLetter = text =>
[...text].map(span)
export const byWord = text =>
text.split(' ').map(span)
Als Nächstes werden diese byLetter()
- und byWord()
-Funktionen importiert und verwendet.
Aufteilen der Orchestrierung
Nachdem die Aufteilungstools einsatzbereit sind, sieht das Ganze so aus:
- Elemente für Splitscreen-Modus auswählen
- Aufteilen und Ersetzen von Text durch HTML
Danach übernimmt CSS und animiert die Elemente / Felder.
Elemente finden
Ich habe Attribute und Werte verwendet, um Informationen zur gewünschten Animation und zur Aufteilung des Texts zu speichern. Ich fand es gut, diese deklarativen Optionen in das HTML einzufügen. Das Attribut split-by
wird von JavaScript verwendet, um Elemente zu finden und Kästen für Buchstaben oder Wörter zu erstellen. Das Attribut letter-animation
oder word-animation
wird von CSS verwendet, um untergeordnete Elemente des Elements anzusprechen und Transformationen und Animationen anzuwenden.
Hier ein Beispiel für HTML, in dem die beiden Attribute verwendet werden:
<h1 split-by="letter" letter-animation="breath">animated letters</h1>
<h1 split-by="word" word-animation="trampoline">hover the words</h1>
Elemente über JavaScript finden
Ich habe die CSS-Selektorsyntax für das Vorhandensein von Attributen verwendet, um die Liste der Elemente zu erstellen, deren Text aufgeteilt werden soll:
const splitTargets = document.querySelectorAll('[split-by]')
Elemente über CSS finden
Außerdem habe ich den Attribut-Anwesenheitsselektor in CSS verwendet, um allen Buchstabenanimationen dieselben Basisstile zu geben. Später verwenden wir den Attributwert, um spezifischere Stile hinzuzufügen und einen Effekt zu erzielen.
letter-animation {
@media (--motionOK) {
/* animation styles */
}
}
Text an Ort und Stelle aufteilen
Für jedes der in JavaScript gefundenen Aufteilungsziele wird der Text anhand des Attributwerts aufgeteilt und jeder String wird einer <span>
zugeordnet. Wir können dann den Text des Elements durch die von uns erstellten Kästen ersetzen:
splitTargets.forEach(node => {
const type = node.getAttribute('split-by')
let nodes = null
if (type === 'letter') {
nodes = byLetter(node.innerText)
}
else if (type === 'word') {
nodes = byWord(node.innerText)
}
if (nodes) {
node.firstChild.replaceWith(...nodes)
}
})
Zusammenfassung der Orchestrierung
index.js
in der Fertigstellung:
import {byLetter, byWord} from './splitting.js'
const {matches:motionOK} = window.matchMedia(
'(prefers-reduced-motion: no-preference)'
)
if (motionOK) {
const splitTargets = document.querySelectorAll('[split-by]')
splitTargets.forEach(node => {
const type = node.getAttribute('split-by')
let nodes = null
if (type === 'letter')
nodes = byLetter(node.innerText)
else if (type === 'word')
nodes = byWord(node.innerText)
if (nodes)
node.firstChild.replaceWith(...nodes)
})
}
Das JavaScript könnte so gelesen werden:
- Importieren Sie einige Hilfsfunktionen.
- Prüfe, ob die Bewegung für diesen Nutzer in Ordnung ist. Wenn nicht, unternimm nichts.
- Für jedes Element, das aufgeteilt werden soll.
- Teilen Sie sie entsprechend auf.
- Text durch Elemente ersetzen.
Animationen und Übergänge aufteilen
Durch die oben beschriebene Manipulation des Aufteilungsdokuments sind nun eine Vielzahl potenzieller Animationen und Effekte mit CSS oder JavaScript möglich. Am Ende dieses Artikels finden Sie einige Links, die Ihnen dabei helfen können, das Potenzial für Aufteilungen zu erkennen.
Jetzt ist es an der Zeit, zu zeigen, was Sie damit anfangen können. Ich zeige Ihnen vier CSS-basierte Animationen und Übergänge. 🤓
Buchstaben aufteilen
Als Grundlage für die Effekte mit geteilten Buchstaben habe ich das folgende CSS verwendet. Ich habe alle Übergänge und Animationen hinter die Media-Query für Bewegung gesetzt und jedem neuen untergeordneten Buchstaben span
eine „display“-Eigenschaft sowie einen Stil für die Behandlung von Leerzeichen zugewiesen:
[letter-animation] > span {
display: inline-block;
white-space: break-spaces;
}
Der Stil für Leerzeichen ist wichtig, damit Spannen, die nur ein Leerzeichen enthalten, nicht von der Layout-Engine zusammengefasst werden. Jetzt kommen wir zu den interessanten, zustandsbehafteten Dingen.
Beispiel für geteilte Buchstaben bei Übergängen
In diesem Beispiel werden CSS-Übergänge für den Effekt mit geteiltem Text verwendet. Für Übergänge benötigen wir Zustände, zwischen denen die Engine animieren kann. Ich habe drei Zustände ausgewählt: kein Hover, Hover im Satz und Hover auf einem Buchstaben.
Wenn der Nutzer den Mauszeiger auf den Satz (Container) bewegt, werden alle untergeordneten Elemente so verkleinert, als hätte der Nutzer sie weiter weg geschoben. Wenn der Nutzer dann den Mauszeiger auf einen Buchstaben bewegt, wird dieser in den Vordergrund gerückt.
@media (--motionOK) {
[letter-animation="hover"] {
&:hover > span {
transform: scale(.75);
}
& > span {
transition: transform .3s ease;
cursor: pointer;
&:hover {
transform: scale(1.25);
}
}
}
}
Beispiel für animierte geteilte Buchstaben
In diesem Beispiel wird eine vordefinierte @keyframe
-Animation verwendet, um jeden Buchstaben unendlich oft zu animieren. Außerdem wird der Inline-Index für benutzerdefinierte Eigenschaften genutzt, um einen Staffeleffekt zu erzeugen.
@media (--motionOK) {
[letter-animation="breath"] > span {
animation:
breath 1200ms ease
calc(var(--index) * 100 * 1ms)
infinite alternate;
}
}
@keyframes breath {
from {
animation-timing-function: ease-out;
}
to {
transform: translateY(-5px) scale(1.25);
text-shadow: 0 0 25px var(--glow-color);
animation-timing-function: ease-in-out;
}
}
Wörter aufteilen
Flexbox hat in diesen Beispielen als Containertyp gut funktioniert, da die Einheit ch
als angemessene Lückenlänge verwendet wurde.
word-animation {
display: inline-flex;
flex-wrap: wrap;
gap: 1ch;
}
Beispiel für geteilte Übergangswörter
In diesem Beispiel für einen Übergang verwende ich wieder den Mauszeiger. Da der Effekt den Inhalt anfangs bis zum Hovern verbirgt, habe ich dafür gesorgt, dass die Interaktion und die Formatierungen nur angewendet werden, wenn das Gerät die Möglichkeit zum Hovern bietet.
@media (hover) {
[word-animation="hover"] {
overflow: hidden;
overflow: clip;
& > span {
transition: transform .3s ease;
cursor: pointer;
&:not(:hover) {
transform: translateY(50%);
}
}
}
}
Beispiel für animierte aufgeteilte Wörter
In diesem Animationsbeispiel verwende ich wieder CSS @keyframes
, um eine gestaffelte, unendliche Animation für einen normalen Textabsatz zu erstellen.
[word-animation="trampoline"] > span {
display: inline-block;
transform: translateY(100%);
animation:
trampoline 3s ease
calc(var(--index) * 150 * 1ms)
infinite alternate;
}
@keyframes trampoline {
0% {
transform: translateY(100%);
animation-timing-function: ease-out;
}
50% {
transform: translateY(0);
animation-timing-function: ease-in;
}
}
Fazit
Jetzt wissen Sie, wie ich es gemacht habe. Wie würden Sie es machen? 🙂
Wir möchten unsere Ansätze diversifizieren und alle Möglichkeiten kennenlernen, die das Web bietet. Erstelle einen Codepen oder hoste deine eigene Demo, sende mir einen Tweet mit dem Link und ich füge sie unten im Abschnitt „Community-Remixe“ hinzu.
Quelle
Weitere Demos und Inspiration
Community-Remixe
<text-hover>
-Webkomponente von gnehcwu auf CodeSandbox