Ein grundlegender Überblick über die Erstellung von Animationen zum Aufteilen von 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 die schrittweise Animation. 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 mit reduzierter 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:
Wenn ein Nutzer weniger Bewegungselemente bevorzugt, lassen wir das HTML-Dokument unverändert und führen keine Animation durch. Wenn Bewegung in Ordnung ist, schneiden wir sie in einzelne Stücke auf. Hier ist eine Vorschau des HTML-Codes, nachdem der Text durch JavaScript in Buchstaben aufgeteilt wurde.
Bewegungsbedingungen werden vorbereitet
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);
Vorbereiten der JS-Bedingung
In JavaScript bietet der Browser eine Möglichkeit, Medienabfragen zu prüfen. Ich habe das boolesche Ergebnis aus der Medienabfrageprüfung mit Destrukturierung extrahiert und umbenannt:
const {matches:motionOK} = window.matchMedia(
'(prefers-reduced-motion: no-preference)'
)
Ich kann dann auf motionOK
prüfen und das Dokument nur ändern, wenn der Nutzer keine Bewegungsreduzierung angefordert hat.
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 untergeordnete Element an einem Ort speichern:
letter-animation {
@media (--motionOK) {
/* animation styles */
}
}
Mit der benutzerdefinierten PostCSS-Eigenschaft und einem booleschen JavaScript-Code können Sie den Effekt unter bestimmten Bedingungen upgraden. 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
Am besten beginnen Sie mit einer Funktion, die einen String verwendet und jeden Buchstaben in einem Array zurückgibt.
export const byLetter = text =>
[...text].map(span)
Die gestreute Syntax von ES6 hat dazu beigetragen, dass diese Aufgabe sehr schnell war.
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 übergeben, das auf eine Aufteilung zwischen Wörtern hinweist.
Dienstprogrammfunktion für Blöcke erstellen
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 ein benutzerdefiniertes Attribut namens --index
mit der Array-Position festgelegt wird. Die Felder für die Buchstabenanimationen sind großartig, aber ein Index zur Verwendung in CSS ist eine scheinbar kleine Ergänzung mit großer Wirkung.
Am auffälligsten ist dabei die Staggering-Funktion.
Wir können --index
verwenden, um Animationen für eine gestaffelte Darstellung zu verschieben.
Schlussfolgerung zu Dienstprogrammen
Das splitting.js
-Modul ist abgeschlossen:
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 lernen Sie, die Funktionen byLetter()
und byWord()
zu importieren und zu verwenden.
Geteilte 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 suchen
Ich habe Attribute und Werte verwendet, um Informationen zur gewünschten Animation und zum Aufteilen des Texts zu speichern. Ich fand es gut, diese deklarativen Optionen in die HTML-Datei einzufügen. 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 die Attributpräsenz in CSS verwendet, um allen Buchstabenanimationen die gleichen 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. Anschließend können wir den Text des Elements durch die Felder ersetzen, die wir erstellt haben:
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)
}
})
Fazit zur Orchestrierung
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)
})
}
Der JavaScript-Code könnte in folgendem Englisch 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 Leerräume ist wichtig, damit die Spannen, die nur Leerzeichen sind, nicht von der Layout-Engine minimiert werden. Nun zu den zustandsorientierten, unterhaltsamen Inhalten.
Beispiel für aufgeteilte Buchstaben mit Wechsel
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 geteilte Buchstaben
In diesem Beispiel wird eine vordefinierte @keyframe
-Animation verwendet, um jeden Buchstaben unendlich zu animieren. Außerdem wird der Inline-Index der benutzerdefinierten 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
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 aufgeteilte Wörter mit Übergang
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