Eine grundlegende Übersicht zum Erstellen von animierten Buchstaben und Wörtern.
In diesem Beitrag möchte ich meine Gedanken zu Möglichkeiten zur Lösung von animierten und interaktiven Textzeilen für das Web teilen, die minimalistisch, barrierefrei und plattformübergreifend sind. Demo ansehen
Wenn du lieber ein Video ansiehst, findest du hier eine YouTube-Version dieses Beitrags:
Übersicht
Textanimationen können sehr beeindruckend sein. In diesem Beitrag streifen wir nur die Oberfläche des Animationspotenzials, aber er bietet eine solide Grundlage, auf der Sie aufbauen können. Das Ziel ist es, die Animation schrittweise zu gestalten. Der Text sollte standardmäßig lesbar sein und die Animation sollte darüber liegen. Bewegungseffekte für geteilten Text können extravagant und potenziell ablenkend sein. Wir bearbeiten daher nur HTML oder wenden Bewegungsstile an, wenn der Nutzer mit Bewegung einverstanden ist.
Hier eine allgemeine Übersicht über den Workflow und die Ergebnisse:
- Bereiten Sie bedingte Variablen für reduzierte Bewegung für CSS und JS vor.
- Vorbereiten von Split-Text-Dienstprogrammen in JavaScript
- Orchestrieren Sie die bedingten Anweisungen und Dienstprogramme beim Seitenaufbau.
- Erstellen Sie CSS-Übergänge und -Animationen für Buchstaben und Wörter (das ist der coole Teil!).
Hier ist eine Vorschau der bedingten Ergebnisse, die wir anstreben:
Wenn ein Nutzer weniger Bewegung bevorzugt, belassen wir das HTML-Dokument unverändert und führen keine Animationen aus. Wenn die Bewegung in Ordnung ist, zerschneiden wir das Bild in Stücke. Hier ist eine Vorschau des HTML-Codes, nachdem der Text durch JavaScript in Buchstaben aufgeteilt wurde.
Bedingte Bewegungsabläufe vorbereiten
Die verfügbare Mediaabfrage @media
(prefers-reduced-motion: reduce)
wird in diesem Projekt in CSS und JavaScript verwendet. Diese Medienabfrage ist unsere primäre Bedingung, um zu entscheiden, ob Text geteilt werden soll oder nicht. Mit der CSS-Medienabfrage werden Übergänge und Animationen unterdrückt, während die JavaScript-Medienabfrage die HTML-Manipulation verhindert.
Bedingte CSS-Anweisung vorbereiten
Ich habe PostCSS verwendet, um die Syntax von Media Queries Level 5 zu aktivieren, mit der ich eine boolesche Mediaabfrage in einer Variablen speichern kann:
@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 nach motionOK
suchen 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 prüfen, indem ich mit PostCSS die @nest
-Syntax aus Nesting Draft 1 aktiviere. So kann ich die gesamte Logik der Animation und die Stilanforderungen für das übergeordnete und die untergeordneten Elemente an einem Ort speichern:
letter-animation {
@media (--motionOK) {
/* animation styles */
}
}
Mit der benutzerdefinierten PostCSS-Eigenschaft und einer JavaScript-Booleschen Variablen können wir den Effekt bedingt aktualisieren. Im nächsten Abschnitt erkläre ich das JavaScript zum Umwandeln von Strings in Elemente.
Text aufteilen
Buchstaben, Wörter, Zeilen usw. können nicht einzeln mit CSS oder JS animiert werden. Um diesen Effekt zu erzielen, benötigen wir Boxen. 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-Dienstfunktionen zum Aufteilen von Strings in Elemente erstellen
- Nutzung dieser Dienstprogramme orchestrieren
Dienstfunktion zum Teilen von Buchstaben
Ein guter Ausgangspunkt ist eine Funktion, die einen String annimmt und jeden Buchstaben in einem Array zurückgibt.
export const byLetter = text =>
[...text].map(span)
Die Spread-Syntax aus ES6 hat diese Aufgabe wirklich vereinfacht.
Dienstfunktion zum Aufteilen von Wörtern
Ähnlich wie bei der Aufteilung von Buchstaben nimmt diese Funktion einen String an und gibt jedes Wort in einem Array zurück.
export const byWord = text =>
text.split(' ').map(span)
Mit der Methode split()
für JavaScript-Strings können wir angeben, an welchen Zeichen das Schneiden erfolgen soll.
Ich habe ein Leerzeichen übersprungen, was eine Trennung zwischen Wörtern bedeutet.
Boxen als Dienstfunktion verwenden
Für den Effekt sind Kästchen für jeden Buchstaben erforderlich. In diesen 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
}
Beachten Sie, dass eine benutzerdefinierte Eigenschaft namens --index
mit der Arrayposition festgelegt wird. Die Felder für die Buchstabenanimationen sind toll, 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 Staggering-Funktion.
Mit --index
können wir die Animationen versetzen, um einen gestaffelten Look zu erzielen.
Fazit zu Dienstprogrammen
Das splitting.js
-Modul im Überblick:
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 importieren und verwenden Sie diese byLetter()
- und byWord()
-Funktionen.
Aufgeteilte Orchestrierung
Die Tools zum Aufteilen sind einsatzbereit. So funktionierts:
- Elemente finden, die Sie teilen möchten
- Sie aufteilen und Text durch HTML ersetzen
Danach übernimmt CSS und animiert die Elemente / Boxen.
Elemente finden
Ich habe Attribute und Werte verwendet, um Informationen zur gewünschten Animation und zum Aufteilen des Texts zu speichern. Ich fand es toll, diese deklarativen Optionen in die HTML-Datei einfügen zu können. Das Attribut split-by
wird in JavaScript verwendet, um Elemente zu finden und Felder für Buchstaben oder Wörter zu erstellen. Das Attribut letter-animation
oder word-animation
wird in CSS verwendet, um Transformationen und Animationen auf Elementkinder anzuwenden.
Hier ein Beispiel für HTML-Code mit den beiden Attributen:
<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 eine Liste der Elemente zu erstellen, deren Text aufgeteilt werden soll:
const splitTargets = document.querySelectorAll('[split-by]')
Elemente aus dem Preisvergleichsportal finden
Außerdem habe ich den Attributpräsenz-Selektor in CSS verwendet, um allen Buchstabenanimationen dieselben Basisstile zuzuweisen. 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 Split-Ziele, die wir in JavaScript finden, wird der Text basierend auf dem Wert des Attributs aufgeteilt und jeder String einer <span>
zugeordnet. Wir können dann den Text des Elements durch die von uns erstellten Felder 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)
}
})
Orchestrierung – Fazit
index.js
abgeschlossen:
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 Dienstprogrammfunktionen.
- Prüfen, ob Bewegung für diesen Nutzer in Ordnung ist. Andernfalls nichts tun.
- Für jedes Element, das aufgeteilt werden soll.
- Sie können sie nach Belieben aufteilen.
- Ersetzen Sie Text durch Elemente.
Animationen und Übergänge aufteilen
Durch die oben beschriebene Dokumentaufteilung stehen Ihnen eine Vielzahl von möglichen Animationen und Effekten mit CSS oder JavaScript zur Verfügung. Am Ende dieses Artikels finden Sie einige Links, die Ihnen als Inspiration dienen können.
Jetzt ist es an der Zeit, zu zeigen, was du damit anfangen kannst. Ich zeige Ihnen vier CSS-basierte Animationen und Übergänge. 🤓
Buchstaben trennen
Als Grundlage für die Effekte der geteilten Buchstaben fand ich das folgende CSS hilfreich. Ich habe alle Übergänge und Animationen hinter die Motion-Media-Abfrage gestellt und dann jedem neuen untergeordneten Buchstaben span
eine Anzeigeeigenschaft sowie einen Stil für die Behandlung von Weißräumen zugewiesen:
[letter-animation] > span {
display: inline-block;
white-space: break-spaces;
}
Der Stil für Weißräume ist wichtig, damit die Spannen, die nur aus einem Leerzeichen bestehen, nicht vom Layout-Engine minimiert werden. Jetzt kommen wir zu den spannenden Dingen.
Beispiel für Übergangsbuchstaben
In diesem Beispiel werden CSS-Übergänge für den Split-Texteffekt verwendet. Für Übergänge benötigen wir Zustände, zwischen denen die Engine animieren kann. Ich habe drei Zustände ausgewählt: kein Hovering, Hovering im Satz und Hovering auf einem Buchstaben.
Wenn der Nutzer den Mauszeiger auf den Satz bzw. den Container bewegt, werden alle untergeordneten Elemente verkleinert, als würde der Nutzer sie weiter wegschieben. Wenn der Nutzer den Mauszeiger auf einen Buchstaben bewegt, wird er hervorgehoben.
@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 Buchstaben
In diesem Beispiel wird eine vordefinierte @keyframe
-Animation verwendet, um jeden Buchstaben unendlich zu animieren. Der Index der benutzerdefinierten Inline-Eigenschaft wird verwendet, um einen Verzögerungseffekt zu erzielen.
@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
In diesen Beispielen hat Flexbox als Containertyp gut funktioniert und die Einheit ch
als angemessene Lücke genutzt.
word-animation {
display: inline-flex;
flex-wrap: wrap;
gap: 1ch;
}
Beispiel für die Aufteilung von Wörtern bei Übergängen
In diesem Beispiel für eine Überleitung verwende ich wieder den Hover-Effekt. Da der Effekt den Inhalt anfangs bis zum Hovering ausblendet, habe ich dafür gesorgt, dass die Interaktion und die Stile nur angewendet wurden, wenn das Gerät die Funktion zum Hovering unterstützte.
@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 geteilte Wörter
In diesem Beispiel verwende ich wieder CSS @keyframes
, um eine versetzte, endlose 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, da Sie wissen, wie ich das gemacht habe, wie würden Sie es machen? 🙂
Lassen Sie uns unsere Ansätze diversifizieren und alle Möglichkeiten kennenlernen, wie Sie im Web entwickeln können. Erstelle einen Codepen oder hoste deine eigene Demo, tweete mir einen Link dazu und ich füge sie unten in den Abschnitt „Community-Remixe“ ein.
Quelle
Weitere Demos und Inspiration
Remixe der Community
<text-hover>
-Webkomponente von gnehcwu in CodeSandbox