Stellen Sie sich Folgendes vor: Sie treten einem neuen Projekt bei, tauchen in die Codebasis ein und entdecken innerhalb der ersten Stunden etwas frustrierend Vertrautes. Über die Stylesheets verteilt finden Sie mehrere @keyframes-Definitionen für dieselben Grundanimationen. Drei verschiedene Einblendeffekte, zwei oder drei Folienvarianten, eine Handvoll Zoom-Animationen und mindestens zwei verschiedene Drehanimationen – warum nicht? @keyframes Puls { von { Maßstab: 1; } zu { Maßstab: 1,1; } }
@keyframes größerer Puls { 0 %, 20 %, 100 % { Maßstab: 1; } 10 %, 40 % { Maßstab: 1,2; } }
Wenn Ihnen dieses Szenario bekannt vorkommt, sind Sie nicht allein. Nach meiner Erfahrung in verschiedenen Projekten ist die Konsolidierung und Standardisierung von Keyframes einer der beständigsten schnellen Erfolge, die ich erzielen kann. Es hat sich zu einem so zuverlässigen Muster entwickelt, dass ich mich nun darauf freue, diese Bereinigung als eine meiner ersten Aufgaben für jede neue Codebasis anzusehen. Die Logik hinter dem Chaos Diese Redundanz macht durchaus Sinn, wenn man darüber nachdenkt. Wir alle verwenden in unserer täglichen Arbeit die gleichen grundlegenden Animationen: Überblendungen, Schiebebewegungen, Zooms, Drehungen und andere gängige Effekte. Diese Animationen sind ziemlich unkompliziert und es ist einfach, schnell eine @keyframes-Definition zu erstellen, um die Arbeit zu erledigen. Ohne ein zentralisiertes Animationssystem schreiben Entwickler diese Keyframes natürlich von Grund auf neu, ohne zu wissen, dass ähnliche Animationen bereits an anderer Stelle in der Codebasis vorhanden sind. Dies ist besonders häufig der Fall, wenn in komponentenbasierten Architekturen gearbeitet wird (was die meisten von uns heutzutage tun), da Teams oft parallel über verschiedene Teile der Anwendung hinweg arbeiten. Das Ergebnis? Animationschaos. Das kleine Problem Die offensichtlichsten Probleme bei der Keyframe-Duplizierung sind verschwendete Entwicklungszeit und unnötiges Aufblähen des Codes. Mehrere Keyframe-Definitionen bedeuten, dass mehrere Stellen aktualisiert werden müssen, wenn sich Anforderungen ändern. Müssen Sie das Timing Ihrer Fade-Animation anpassen? Sie müssen jede Instanz in Ihrer Codebasis aufspüren. Möchten Sie Beschleunigungsfunktionen standardisieren? Viel Glück beim Finden aller Variationen. Diese Vervielfachung der Wartungspunkte macht selbst einfache Animationsaktualisierungen zu einer zeitaufwändigen Aufgabe. Das größere Problem Diese Keyframe-Duplizierung führt zu einem viel heimtückischeren Problem, das unter der Oberfläche lauert: der globalen Scope-Falle. Auch bei der Arbeit mit komponentenbasierten Architekturen werden CSS-Keyframes immer im globalen Bereich definiert. Das bedeutet, dass alle Keyframes für alle Komponenten gelten. Stets. Ja, Ihre Animation verwendet nicht unbedingt die Keyframes, die Sie in Ihrer Komponente definiert haben. Es werden die letzten Keyframes verwendet, die mit genau demselben Namen übereinstimmen und in den globalen Bereich geladen wurden. Solange alle Ihre Keyframes identisch sind, scheint dies ein kleines Problem zu sein. Aber sobald Sie eine Animation für einen bestimmten Anwendungsfall anpassen möchten, stecken Sie in Schwierigkeiten oder, schlimmer noch, Sie sind derjenige, der sie verursacht. Entweder funktioniert Ihre Animation nicht, weil eine andere Komponente nach Ihrer geladen wird und Ihre Keyframes überschreibt, oder Ihre Komponente wird zuletzt geladen und ändert versehentlich das Animationsverhalten für jede andere Komponente, die den Namen dieses Keyframes verwendet, und Sie bemerken es möglicherweise nicht einmal. Hier ist ein einfaches Beispiel, das das Problem verdeutlicht: .component-one { /* Komponentenstile */ Animation: Puls 1s Easy-in-out unendlich abwechselnd; }
/* diese @keyframes-Definition wird nicht funktionieren */ @keyframes Puls { von { Maßstab: 1; } zu { Maßstab: 1,1; } }
/* später im Code... */
.component-two { /* Komponentenstile */ Animation: Puls 1s Easy-in-out unendlich; }
/* Diese Keyframes gelten für beide Komponenten */ @keyframes Puls { 0 %, 20 %, 100 % { Maßstab: 1; } 10 %, 40 % { Maßstab: 1,2; } }
Beide Komponenten verwenden denselben Animationsnamen, aber die zweite @keyframes-Definition überschreibt die erste. Jetzt verwenden sowohl Komponente eins als auch Komponente zwei die zweiten Keyframes, unabhängig davon, welche Komponente welche Keyframes definiert hat. Sehen Sie sich die Pen Keyframes Tokens – Demo 1 [forked] von Amit Sheen an. Das Schlimmste? Dies funktioniert in der lokalen Entwicklung oft perfekt, bricht jedoch in der Produktion auf mysteriöse Weise ab, wenn Build-Prozesse die Ladereihenfolge Ihrer Stylesheets ändern. Am Ende erhalten Sie Animationen, die sich je nachdem, welche Komponenten in welcher Reihenfolge geladen werden, unterschiedlich verhalten. Die Lösung: Einheitliche Keyframes Die Antwort auf dieses Chaos ist überraschend einfach: vordefinierte dynamische Keyframes, die in einem gemeinsamen Stylesheet gespeichert sind. Anstatt jede Komponente ihre eigenen Animationen definieren zu lassen, erstellen wir zentralisierte Keyframes, die gut dokumentiert und einfach zu verwenden sindnutzbar, wartbar und auf die spezifischen Anforderungen Ihres Projekts zugeschnitten. Betrachten Sie es als Keyframe-Token. So wie wir Token für Farben und Abstände verwenden und viele von uns bereits Token für Animationseigenschaften wie Dauer und Beschleunigungsfunktionen verwenden, warum nicht auch Token für Keyframes verwenden? Dieser Ansatz lässt sich auf natürliche Weise in jeden aktuellen Design-Token-Workflow integrieren, den Sie verwenden, und löst dabei sowohl das kleine Problem (Codeduplizierung) als auch das größere Problem (globale Bereichskonflikte) auf einmal. Die Idee ist einfach: Erstellen Sie eine einzige Quelle der Wahrheit für alle unsere gängigen Animationen. Dieses freigegebene Stylesheet enthält sorgfältig erstellte Keyframes, die die Animationsmuster abdecken, die unser Projekt tatsächlich verwendet. Kein Rätselraten mehr, ob irgendwo in unserer Codebasis bereits eine Fade-Animation vorhanden ist. Kein versehentliches Überschreiben von Animationen anderer Komponenten mehr. Aber hier ist der Schlüssel: Es handelt sich nicht nur um statische Copy-Paste-Animationen. Sie sind so konzipiert, dass sie dynamisch und über benutzerdefinierte CSS-Eigenschaften anpassbar sind, sodass wir die Konsistenz wahren und gleichzeitig die Flexibilität haben, Animationen an bestimmte Anwendungsfälle anzupassen, beispielsweise wenn Sie eine etwas größere „Puls“-Animation an einer Stelle benötigen. Erstellen des ersten Keyframes-Tokens Eine der ersten tief hängenden Früchte, die wir in Angriff nehmen sollten, ist die „Einblend“-Animation. In einem meiner letzten Projekte habe ich über ein Dutzend separate Einblenddefinitionen gefunden, und ja, sie haben alle einfach die Deckkraft von 0 auf 1 animiert. Erstellen wir also ein neues Stylesheet, nennen es kf-tokens.css, importieren es in unser Projekt und platzieren unsere Keyframes mit den richtigen Kommentaren darin. /* keyframes-tokens.css */
/* * Einblenden – Eingangsanimation einblenden * Verwendung: Animation: kf-fade-in 0,3s easy-out; */ @keyframes kf-fade-in { von { Deckkraft: 0; } zu { Deckkraft: 1; } }
Diese einzelne @keyframes-Deklaration ersetzt alle verstreuten Einblendanimationen in unserer Codebasis. Sauber, einfach und weltweit einsetzbar. Und jetzt, da wir dieses Token definiert haben, können wir es von jeder Komponente in unserem Projekt verwenden: .modal { Animation: kf-fade-in 0,3 s Easy-out; }
.tooltip { Animation: kf-fade-in 0,2 s Easy-in-out; }
.notification { Animation: kf-fade-in 0,5 s Easy-out; }
Sehen Sie sich die Pen Keyframes Tokens – Demo 2 [forked] von Amit Sheen an. Hinweis: Wir verwenden in allen unseren @keyframes-Namen das Präfix kf-. Dieses Präfix dient als Namespace, der Namenskonflikte mit vorhandenen Animationen im Projekt verhindert und sofort klar macht, dass diese Keyframes aus unserer Keyframes-Token-Datei stammen. Erstellen einer dynamischen Folie Die KF-Einblend-Keyframes funktionieren großartig, weil sie einfach sind und wenig Spielraum für Unordnung lassen. Bei anderen Animationen müssen wir jedoch viel dynamischer vorgehen, und hier können wir die enorme Leistungsfähigkeit der benutzerdefinierten CSS-Eigenschaften nutzen. Hier glänzen Keyframes-Tokens im Vergleich zu verstreuten statischen Animationen wirklich. Nehmen wir ein häufiges Szenario: „Slide-in“-Animationen. Aber von wo aus reinschlüpfen? 100px von rechts? 50 % von links? Sollte es vom oberen Bildschirmrand eintreten? Oder vielleicht von unten hineinschweben? So viele Möglichkeiten, aber anstatt separate Keyframes für jede Richtung und jede Variation zu erstellen, können wir einen flexiblen Token erstellen, der sich an alle Szenarien anpasst: /* * Slide In – gerichtete Slide-Animation * Verwenden Sie --kf-slide-from, um die Richtung zu steuern * Standard: gleitet von links hinein (-100 %). * Verwendung: * Animation: kf-slide-in 0,3s easy-out; * --kf-slide-from: -100px 0; // von links gleiten * --kf-slide-from: 100px 0; // von rechts gleiten * --kf-slide-from: 0 -50px; // von oben gleiten */
@keyframes kf-slide-in { von { übersetzen: var(--kf-slide-from, -100% 0); } zu { übersetzen: 0 0; } }
Jetzt können wir dieses einzelne @keyframes-Token für jede Folienrichtung verwenden, indem wir einfach die benutzerdefinierte Eigenschaft --kf-slide-from ändern: .sidebar { Animation: kf-slide-in 0,3s easy-out; /* Verwendet den Standardwert: gleitet von links */ }
.notification { Animation: kf-slide-in 0,4s easy-out; --kf-slide-from: 0 -50px; /* von oben gleiten */ }
.modal { Animation: kf-Einblendung 0,5s, kf-slide-in 0,5s kubischer Bezier(0,34, 1,56, 0,64, 1); --kf-slide-from: 50px 50px; /* von unten nach rechts gleiten */ }
Dieser Ansatz gibt uns unglaubliche Flexibilität bei gleichzeitiger Wahrung der Konsistenz. Eine Keyframe-Deklaration, unendliche Möglichkeiten. Sehen Sie sich die Pen Keyframes Tokens – Demo 3 [forked] von Amit Sheen an. Und wenn wir unsere Animationen noch flexibler gestalten und auch „Slide-out“-Effekte ermöglichen möchten, können wir das tunFügen Sie einfach eine benutzerdefinierte Eigenschaft --kf-slide-to hinzu, ähnlich wie im nächsten Abschnitt. Bidirektionale Zoom-Keyframes Eine weitere häufige Animation, die projektübergreifend dupliziert wird, sind „Zoom“-Effekte. Ganz gleich, ob es sich um eine subtile Vergrößerung für Toastnachrichten, eine dramatische Vergrößerung für Modalitäten oder einen sanften Verkleinerungseffekt für Überschriften handelt – Zoom-Animationen gibt es überall. Anstatt für jeden Skalenwert separate Keyframes zu erstellen, erstellen wir einen flexiblen Satz von kf-zoom-Keyframes:
/* * Zoom – Animation skalieren * Verwenden Sie --kf-zoom-from und --kf-zoom-to, um Skalenwerte zu steuern * Standard: Zoomt von 80 % auf 100 % (0,8 bis 1) * Verwendung: * Animation: KF-Zoom 0,2 s Ease-Out; * --kf-zoom-from: 0,5; --kf-zoom-to: 1; // Zoom von 50 % auf 100 % * --kf-zoom-from: 1; --kf-zoom-to: 0; // von 100 % auf 0 % zoomen * --kf-zoom-from: 1; --kf-zoom-to: 1.1; // von 100 % auf 110 % zoomen */
@keyframes kf-zoom { von { Maßstab: var(--kf-zoom-from, 0,8); } zu { Maßstab: var(--kf-zoom-to, 1); } }
Mit einer Definition können wir jede benötigte Zoomvariation erreichen: .toast { Animation: kf-Einschub 0,2s, KF-Zoom 0,4 Sek. Ease-Out; --kf-slide-from: 0 100 %; /* von oben gleiten */ /* Verwendet Standardzoom: skaliert von 80 % bis 100 % */ }
.modal { Animation: kf-zoom 0,3s kubischer Bezier(0,34, 1,56, 0,64, 1); --kf-zoom-from: 0; /* dramatischer Zoom von 0 % auf 100 % */ }
.überschrift { Animation: kf-fade-in 2s, KF-Zoom 2s Ease-In; --kf-zoom-from: 1.2; --kf-zoom-to: 0,8; /* sanft verkleinern */ }
Der Standardwert von 0,8 (80 %) funktioniert perfekt für die meisten UI-Elemente, wie Toastnachrichten und Karten, lässt sich aber dennoch leicht für Sonderfälle anpassen. Sehen Sie sich die Pen Keyframes Tokens – Demo 4 [forked] von Amit Sheen an. Vielleicht ist Ihnen in den letzten Beispielen etwas Interessantes aufgefallen: Wir haben Animationen kombiniert. Einer der Hauptvorteile der Arbeit mit @keyframes-Tokens besteht darin, dass sie so konzipiert sind, dass sie sich nahtlos ineinander integrieren lassen. Diese sanfte Komposition ist gewollt und nicht zufällig. Wir werden die Animationskomposition später ausführlicher besprechen und auch dort besprechen, wo sie problematisch werden kann, aber die meisten Kombinationen sind unkompliziert und leicht zu implementieren. Hinweis: Während ich diesen Artikel schrieb, und vielleicht gerade weil ich ihn schrieb, überlegte ich die gesamte Idee der Eingangsanimationen noch einmal. Brauchen wir sie trotz all der jüngsten Fortschritte bei CSS überhaupt noch? Glücklicherweise ging Adam Argyle denselben Fragen nach und formulierte sie in seinem Blog hervorragend. Dies steht nicht im Widerspruch zu dem, was hier geschrieben wird, stellt jedoch einen erwägenswerten Ansatz dar, insbesondere wenn Ihre Projekte stark auf Eingangsanimationen angewiesen sind. Kontinuierliche Animationen Während Eingangsanimationen wie „Ausblenden“, „Schieben“ und „Zoomen“ einmal ablaufen und dann anhalten, werden kontinuierliche Animationen auf unbestimmte Zeit wiederholt, um Aufmerksamkeit zu erregen oder laufende Aktivitäten anzuzeigen. Die beiden häufigsten kontinuierlichen Animationen, denen ich begegne, sind „Spin“ (für Ladeindikatoren) und „Pulse“ (für die Hervorhebung wichtiger Elemente). Diese Animationen stellen besondere Herausforderungen dar, wenn es um die Erstellung von Keyframe-Tokens geht. Im Gegensatz zu Eingangsanimationen, die normalerweise von einem Zustand in einen anderen wechseln, müssen kontinuierliche Animationen in ihren Verhaltensmustern hochgradig anpassbar sein. Der Spin Doctor Jedes Projekt scheint mehrere Spin-Animationen zu verwenden. Manche drehen sich im Uhrzeigersinn, andere gegen den Uhrzeigersinn. Manche machen eine einzelne 360-Grad-Drehung, andere machen mehrere Drehungen, um einen schnelleren Effekt zu erzielen. Anstatt für jede Variation separate Keyframes zu erstellen, erstellen wir einen flexiblen Spin, der alle Szenarien abdeckt:
/* * Spin – Rotationsanimation * Verwenden Sie --kf-spin-from und --kf-spin-to, um den Rotationsbereich zu steuern * Verwenden Sie --kf-spin-turns, um den Rotationsbetrag zu steuern * Standard: dreht sich von 0 Grad bis 360 Grad (1 volle Umdrehung) * Verwendung: * Animation: kf-spin 1s linear unendlich; * --kf-spin-turns: 2; // 2 volle Umdrehungen * --kf-spin-from: 0deg; --kf-spin-to: 180deg; // halbe Drehung * --kf-spin-from: 0deg; --kf-spin-to: -360deg; // gegen den Uhrzeigersinn */
@keyframes kf-spin { von { drehen: var(--kf-spin-from, 0deg); } zu { drehen: calc(var(--kf-spin-from, 0deg) + var(--kf-spin-to, 360deg) * var(--kf-spin-turns, 1)); } }
Jetzt können wir jede gewünschte Spin-Variante erstellen:
.loading-spinner { Animation: kf-spin 1s linear unendlich; /* Verwendet die Standardeinstellung: dreht sich von 0 Grad auf 360 Grad */ }
.fast-loader { Animation: kf-spin 1,2s Easy-in-out unendliche Alternative; --kf-spin-turns: 3; /* 3 volle Umdrehungen für jede Richtung pro Zyklus*/ }
.steped-reverse { Animation: kf-spin 1,5s Schritte(8) unendlich; --kf-spin-to: -360deg; /* gegen den Uhrzeigersinn */ }
.subtle-wiggle { Animation: kf-spin 2s easy-in-out unendlich abwechselnd; --kf-spin-from: -16deg; --kf-spin-to: 32deg; /* 36 Grad wackeln: zwischen -18 Grad und +18 Grad */ }
Sehen Sie sich die Pen Keyframes Tokens – Demo 5 [forked] von Amit Sheen an. Das Schöne an diesem Ansatz ist, dass dieselben Keyframes zum Laden von Spinnern, rotierenden Symbolen, Wackeleffekten und sogar komplexen Animationen mit mehreren Drehungen funktionieren. Das Pulsparadoxon Pulsanimationen sind schwieriger, da sie verschiedene Eigenschaften „pulsieren“ können. Einige pulsieren die Skala, andere pulsieren die Deckkraft und einige pulsieren Farbeigenschaften wie Helligkeit oder Sättigung. Anstatt für jede Eigenschaft separate Keyframes zu erstellen, können wir Keyframes erstellen, die mit jeder CSS-Eigenschaft funktionieren. Hier ist ein Beispiel für einen Pulse-Keyframe mit Skalierungs- und Deckkraftoptionen:
/* * Pulse – pulsierende Animation * Verwenden Sie --kf-pulse-scale-from und --kf-pulse-scale-to, um den Skalenbereich zu steuern * Verwenden Sie --kf-pulse-opacity-from und --kf-pulse-opacity-to, um den Deckkraftbereich zu steuern * Standard: kein Impuls (alle Werte 1) * Verwendung: * Animation: kf-pulse 2s Easy-in-out unendlicher Wechsel; * --kf-pulse-scale-from: 0,95; --kf-pulse-scale-to: 1,05; // Skalenimpuls * --kf-pulse-opacity-from: 0,7; --kf-pulse-opacity-to: 1; // Opazitätsimpuls */
@keyframes kf-pulse { von { Skala: var(--kf-pulse-scale-from, 1); Deckkraft: var(--kf-pulse-opacity-from, 1); } zu { Skala: var(--kf-pulse-scale-to, 1); Deckkraft: var(--kf-pulse-opacity-to, 1); } }
Dadurch entsteht ein flexibler Impuls, der mehrere Eigenschaften animieren kann: .Call-to-Action { Animation: kf-pulse 0,6s unendlich abwechselnd; --kf-pulse-opacity-from: 0,5; /* Opazitätsimpuls */ }
.notification-dot { Animation: kf-pulse 0,6 s Ease-in-out unendlich abwechselnd; --kf-pulse-scale-from: 0,9; --kf-pulse-scale-to: 1.1; /* Skalenimpuls */ }
.text-highlight { Animation: KF-Puls 1,5 s Ease-out unendlich; --kf-pulse-scale-from: 0,8; --kf-pulse-opacity-from: 0,2; /* Skalierung und Opazitätsimpuls */ }
Sehen Sie sich die Pen Keyframes Tokens – Demo 6 [forked] von Amit Sheen an. Dieser einzelne kf-pulse-Keyframe kann alles bewältigen, von subtiler Aufmerksamkeitserregung bis hin zu dramatischen Highlights, und ist dabei einfach anzupassen. Erweiterte Lockerung Das Tolle an der Verwendung von Keyframes-Tokens ist, wie einfach es ist, unsere Animationsbibliothek zu erweitern und Effekte bereitzustellen, die die meisten Entwickler nicht von Grund auf neu schreiben würden, wie z. B. Elastic oder Bounce. Hier ist ein Beispiel für ein einfaches „Bounce“-Keyframe-Token, das eine benutzerdefinierte Eigenschaft --kf-bounce-from verwendet, um die Sprunghöhe zu steuern. /* * Bounce – hüpfende Eingangsanimation * Verwenden Sie --kf-bounce-from, um die Sprunghöhe zu steuern * Standard: Sprünge von 100 Vh (außerhalb des Bildschirms) * Verwendung: * Animation: KF-Bounce 3s Easy-In; * --kf-bounce-from: 200px; // aus 200px Höhe springen */
@keyframes kf-bounce { 0 % { übersetzen: 0 calc(var(--kf-bounce-from, 100vh) * -1); }
34 % { übersetzen: 0 calc(var(--kf-bounce-from, 100vh) * -0.4); }
55 % { übersetzen: 0 calc(var(--kf-bounce-from, 100vh) * -0.2); }
72 % { übersetzen: 0 calc(var(--kf-bounce-from, 100vh) * -0.1); }
85 % { übersetzen: 0 calc(var(--kf-bounce-from, 100vh) * -0.05); }
94 % { übersetzen: 0 calc(var(--kf-bounce-from, 100vh) * -0.025); }
99 % { übersetzen: 0 calc(var(--kf-bounce-from, 100vh) * -0.0125); }
22 %, 45 %, 64 %, 79 %, 90 %, 97 %, 100 % { übersetzen: 0 0; Animation-Timing-Funktion: Ease-Out; } }
Animationen wie „elastisch“ sind aufgrund der Berechnungen innerhalb der Keyframes etwas schwieriger. Wir müssen --kf-elastic-from-X und --kf-elastic-from-Y separat definieren (beide sind optional), und zusammen können wir von jedem Punkt auf dem Bildschirm aus einen elastischen Eingang erstellen.
/* * Elastic In – elastische Eingangsanimation * Verwenden Sie --kf-elastic-from-X und --kf-elastic-from-Y, um die Startposition zu steuern * Standard: Eintritt von oben in der Mitte (0, -100 Vh) * Verwendung: * Animation: kf-elastisch-in 2s easy-in-out beide; * --kf-elastic-from-X: -50px; * --kf-elastic-from-Y: -200px; // eingeben von (-50px, -200px) */
@keyframes kf-elastic-in { 0 % { übersetzen: calc(var(--kf-elastic-from-X, -50vw) * 1) calc(var(--kf-elastic-from-Y, 0px) * 1); }
16 % { übersetzen: calc(var(--kf-elastic-from-X, -50vw) * -0.3227) calc(var(--kf-elastic-from-Y, 0px) * -0.3227); }
28 % { übersetzen: calc(var(--kf-elastic-from-X, -50vw) * 0,1312)calc(var(--kf-elastic-from-Y, 0px) * 0,1312); }
44 % { übersetzen: calc(var(--kf-elastic-from-X, -50vw) * -0.0463) calc(var(--kf-elastic-from-Y, 0px) * -0.0463); }
59 % { übersetzen: calc(var(--kf-elastic-from-X, -50vw) * 0,0164) calc(var(--kf-elastic-from-Y, 0px) * 0,0164); }
73 % { übersetzen: calc(var(--kf-elastic-from-X, -50vw) * -0.0058) calc(var(--kf-elastic-from-Y, 0px) * -0.0058); }
88 % { übersetzen: calc(var(--kf-elastic-from-X, -50vw) * 0,0020) calc(var(--kf-elastic-from-Y, 0px) * 0,0020); }
100 % { übersetzen: 0 0; } }
Dieser Ansatz erleichtert die Wiederverwendung und Anpassung erweiterter Keyframes in unserem gesamten Projekt, indem einfach eine einzige benutzerdefinierte Eigenschaft geändert wird.
.bounce-and-zoom { Animation: kf-bounce 3s easy-in, kf-zoom 3s linear; --kf-zoom-from: 0; }
.bounce-and-slide { Animationskomposition: hinzufügen; /* Beide Animationen verwenden Translate */ Animation: kf-bounce 3s easy-in, kf-slide-in 3s easy-out; --kf-slide-from: -200px; }
.elastisch-in { Animation: kf-elastisch-in 2s easy-in-out beide; }
Sehen Sie sich die Pen Keyframes Tokens – Demo 7 [forked] von Amit Sheen an. Bisher haben wir gesehen, wie wir Keyframes auf intelligente und effiziente Weise konsolidieren können. Natürlich möchten Sie vielleicht Dinge optimieren, um sie besser an die Anforderungen Ihres Projekts anzupassen, aber wir haben Beispiele für mehrere gängige Animationen und alltägliche Anwendungsfälle behandelt. Und mit diesen Keyframes-Tokens verfügen wir nun über leistungsstarke Bausteine für die Erstellung konsistenter, wartbarer Animationen im gesamten Projekt. Keine duplizierten Keyframes mehr, keine globalen Bereichskonflikte mehr. Einfach eine saubere und bequeme Möglichkeit, alle unsere Animationsanforderungen zu erfüllen. Aber die eigentliche Frage ist: Wie setzen wir diese Bausteine zusammen? Alles zusammenfügen Wir haben gesehen, dass die Kombination grundlegender Keyframes-Tokens einfach ist. Wir brauchen nichts Besonderes, außer die erste Animation zu definieren, die zweite zu definieren, die Variablen nach Bedarf festzulegen und fertig. /* Einblenden + Einschieben */ .toast { Animation: kf-Einblendung 0,4 s, kf-slide-in 0,4s kubischer Bezier(0,34, 1,56, 0,64, 1); --kf-slide-from: 0 40px; }
/* Vergrößern + Einblenden */ .modal { Animation: kf-Einblendung 0,3s, kf-zoom 0,3s kubisch-bezier(0,34, 1,56, 0,64, 1); --kf-zoom-from: 0,7; --kf-zoom-to: 1; }
/* Einschieben + Pulsieren */ .notification { Animation: kf-Einschub 0,5s, kf-Impuls 1,2 s Ease-in-out unendlich abwechselnd; --kf-slide-from: -100px 0; --kf-pulse-scale-from: 0,95; --kf-pulse-scale-to: 1,05; }
Diese Kombinationen funktionieren wunderbar, da jede Animation auf eine andere Eigenschaft abzielt: Deckkraft, Transformation (Übersetzen/Skalieren) usw. Aber manchmal gibt es Konflikte, und wir müssen wissen, warum und wie wir damit umgehen sollen. Wenn zwei Animationen versuchen, dieselbe Eigenschaft zu animieren – beispielsweise beide animieren die Skalierung oder beide animieren die Deckkraft – wird das Ergebnis nicht Ihren Erwartungen entsprechen. Standardmäßig wird nur eine der Animationen tatsächlich auf diese Eigenschaft angewendet, nämlich die letzte in der Animationsliste. Dies ist eine Einschränkung bei der Art und Weise, wie CSS mehrere Animationen auf derselben Eigenschaft verarbeitet. Dies funktioniert beispielsweise nicht wie vorgesehen, da nur die kf-pulse-Animation angewendet wird. .bad-combo { Animation: kf-zoom 0,5s vorwärts, kf-Impuls 1,2s unendlich abwechselnd; --kf-zoom-from: 0,5; --kf-zoom-to: 1.2; --kf-pulse-scale-from: 0,8; --kf-pulse-scale-to: 1.1; }
Animationszusatz Die einfachste und direkteste Möglichkeit, mehrere Animationen zu verarbeiten, die sich auf dieselbe Eigenschaft auswirken, ist die Verwendung der Eigenschaft „animation-composition“. Im letzten Beispiel oben ersetzt die kf-pulse-Animation die kf-zoom-Animation, sodass wir den anfänglichen Zoom nicht sehen und nicht den erwarteten Maßstab von 1,2 erhalten. Indem wir die hinzuzufügende Animationskomposition festlegen, weisen wir den Browser an, beide Animationen zu kombinieren. Dadurch erhalten wir das gewünschte Ergebnis. .component-two { Animationskomposition: hinzufügen; }
Sehen Sie sich die Pen Keyframes Tokens – Demo 8 [forked] von Amit Sheen an. Dieser Ansatz funktioniert in den meisten Fällen gut, in denen wir Effekte auf dieselbe Eigenschaft kombinieren möchten. Es ist auch nützlich, wenn wir Animationen mit statischen Eigenschaftswerten kombinieren müssen. Wenn wir beispielsweise ein Element haben, das die Eigenschaft „translate“ verwendet, um es genau an der gewünschten Stelle zu positionieren, und es dann mit den kf-slide-in-Keyframes animieren möchten, erhalten wir ohne Animationskomposition einen unangenehmen sichtbaren Sprung. Sehen Sie sich die Pen Keyframes Tokens – Demo 9 [forked] von Amit Sheen an. Wenn die Animationskomposition auf „Hinzufügen“ eingestellt ist, wird die Animation reibungslos mit der vorhandenen kombinierttransformieren, sodass das Element an Ort und Stelle bleibt und wie erwartet animiert wird. Animationsstaffel Eine andere Möglichkeit, mit mehreren Animationen umzugehen, besteht darin, sie zu „versetzen“, d. h. die zweite Animation kurz nach dem Ende der ersten zu starten. Es ist keine Lösung, die in jedem Fall funktioniert, aber sie ist nützlich, wenn wir eine Eingangsanimation haben, auf die eine kontinuierliche Animation folgt. /* Einblenden + Deckkraftimpuls */ .notification { Animation: kf-fade-in 2s easy-out, kf-Impuls 0,5 s 2 s Ease-in-out unendlich abwechselnd; --kf-pulse-opacity-to: 0,5; }
Sehen Sie sich die Pen Keyframes Tokens – Demo 10 [forked] von Amit Sheen an. Ordnungsangelegenheiten Ein großer Teil der Animationen, mit denen wir arbeiten, verwenden die Transformationseigenschaft. In den meisten Fällen ist das einfach bequemer. Es bietet auch einen Leistungsvorteil, da Transformationsanimationen GPU-beschleunigt werden können. Wenn wir jedoch Transformationen verwenden, müssen wir akzeptieren, dass die Reihenfolge, in der wir unsere Transformationen durchführen, wichtig ist. Eine Menge. In unseren bisherigen Keyframes haben wir individuelle Transformationen verwendet. Gemäß den Spezifikationen werden diese immer in einer festen Reihenfolge angewendet: Zuerst wird das Element verschoben, dann gedreht und dann skaliert. Das macht Sinn und ist das, was die meisten von uns erwarten. Wenn wir jedoch die Transformationseigenschaft verwenden, ist die Reihenfolge, in der die Funktionen geschrieben werden, auch die Reihenfolge, in der sie angewendet werden. Wenn wir in diesem Fall etwas um 100 Pixel auf der X-Achse verschieben und es dann um 45 Grad drehen, ist das nicht dasselbe, als ob wir es zuerst um 45 Grad drehen und dann um 100 Pixel verschieben. /* Rosa Quadrat: Erst verschieben, dann drehen */ .example-one { transformieren: translatorX(100px) rotieren(45deg); }
/* Grünes Quadrat: Erst drehen, dann verschieben */ .example-two { transformieren: rotieren (45 Grad) übersetzenX (100 Pixel); }
Sehen Sie sich die Pen Keyframes Tokens – Demo 11 [forked] von Amit Sheen an. Aber gemäß der Transformationsreihenfolge erfolgen alle einzelnen Transformationen – alles, was wir für die Keyframe-Tokens verwendet haben – vor den Transformationsfunktionen. Das bedeutet, dass alles, was Sie in der Transformationseigenschaft festlegen, nach den Animationen geschieht. Wenn Sie jedoch beispielsweise die Übersetzung zusammen mit den kf-spin-Keyframes festlegen, erfolgt die Übersetzung vor der Animation. Noch verwirrt?! Dies führt zu Situationen, in denen statische Werte zu unterschiedlichen Ergebnissen für dieselbe Animation führen können, wie im folgenden Fall:
/* Gemeinsame Animation für beide Spinner */ .spinner { Animation: kf-spin 1s linear unendlich; }
/* Rosa Spinner: Vor dem Drehen übersetzen (individuelle Transformation) */ .spinner-pink { übersetzen: 100 % 50 %; }
/* Grüner Spinner: Drehen, dann verschieben (Funktionsreihenfolge) */ .spinner-green { transform: Translate(100%, 50%); }
Sehen Sie sich die Pen Keyframes Tokens – Demo 12 [forked] von Amit Sheen an. Sie können sehen, dass der erste Spinner (rosa) eine Verschiebung erhält, die vor der Drehung von kf-spin erfolgt, sodass er sich zunächst an seinen Platz bewegt und sich dann dreht. Der zweite Spinner (grün) erhält eine Funktion „translate()“, die nach der einzelnen Transformation ausgeführt wird, sodass sich das Element zuerst dreht und sich dann relativ zu seinem aktuellen Winkel bewegt, und wir erhalten den Effekt einer weiten Umlaufbahn. Nein, das ist kein Fehler. Dies ist nur eines der Dinge, die wir über CSS wissen und berücksichtigen müssen, wenn wir mit mehreren Animationen oder mehreren Transformationen arbeiten. Bei Bedarf können Sie auch einen zusätzlichen Satz von kf-spin-alt-Keyframes erstellen, die Elemente mithilfe der Funktion „rotate()“ drehen. Reduzierte Bewegung Und während wir über alternative Keyframes sprechen, können wir die Option „Keine Animation“ nicht ignorieren. Einer der größten Vorteile der Verwendung von Keyframes-Tokens besteht darin, dass die Barrierefreiheit integriert werden kann, und das ist eigentlich ganz einfach. Indem wir unsere Keyframes unter Berücksichtigung der Barrierefreiheit entwerfen, können wir sicherstellen, dass Benutzer, die eine reduzierte Bewegung bevorzugen, ein flüssigeres, weniger ablenkendes Erlebnis erhalten, ohne zusätzliche Arbeit oder Codeduplizierung. Die genaue Bedeutung von „Reduced Motion“ kann sich von einer Animation zur anderen und von Projekt zu Projekt etwas ändern, aber hier sind ein paar wichtige Punkte, die Sie beachten sollten: Stummschalten von Keyframes Während einige Animationen abgeschwächt oder verlangsamt werden können, sollten andere vollständig verschwinden, wenn eine reduzierte Bewegung gewünscht wird. Pulsanimationen sind ein gutes Beispiel. Um sicherzustellen, dass diese Animationen nicht im reduzierten Bewegungsmodus ausgeführt werden, können wir sie einfach in die entsprechende Medienabfrage einbinden.
@media (prefers-reduced-motion: no-preference) { @keyfrmaes kf-pulse { von { Skala: var(--kf-pulse-scale-from, 1); Deckkraft: var(--kf-pulse-opacity-from, 1); } zu { Skala: var(--kf-pulse-scale-to, 1); Opazität:var(--kf-pulse-opacity-to, 1); } } }
Dadurch wird sichergestellt, dass Benutzer, die Preferences-Reduced-Motion auf „Reduction“ eingestellt haben, die Animation nicht sehen und ein Erlebnis erhalten, das ihren Vorlieben entspricht. Sofort rein Es gibt einige Keyframes, die wir nicht einfach entfernen können, beispielsweise Eingangsanimationen. Der Wert muss sich ändern, muss beleben; Andernfalls hat das Element nicht die richtigen Werte. Bei reduzierter Bewegung sollte dieser Übergang vom Anfangswert jedoch sofort erfolgen. Um dies zu erreichen, definieren wir einen zusätzlichen Satz von Keyframes, bei denen der Wert sofort in den Endzustand springt. Diese werden zu unseren Standard-Keyframes. Anschließend fügen wir die regulären Keyframes in eine Medienabfrage für Prefers-Reduced-Motion ein, die auf No-Preference gesetzt ist, genau wie im vorherigen Beispiel. /* Sofort einblenden für reduzierte Bewegung */ @keyframes kf-zoom { von, bis { Maßstab: var(--kf-zoom-to, 1); } }
@media (prefers-reduced-motion: no-preference) { /* Ursprüngliche Zoom-Keyframes */ @keyframes kf-zoom { von { Maßstab: var(--kf-zoom-from, 0,8); } zu { Maßstab: var(--kf-zoom-to, 1); } } }
Auf diese Weise sehen Benutzer, die eine reduzierte Bewegung bevorzugen, das Element sofort in seinem endgültigen Zustand, während alle anderen den animierten Übergang sehen. Der sanfte Ansatz Es gibt Fälle, in denen wir etwas Bewegung beibehalten möchten, aber viel sanfter und ruhiger als die Originalanimation. Beispielsweise können wir einen hüpfenden Eingang durch eine sanfte Einblendung ersetzen.
@keyframes kf-bounce { /* Sanftes Einblenden für reduzierte Bewegung */ }
@media (prefers-reduced-motion: no-preference) { @keyframes kf-bounce { /* Ursprüngliche Bounce-Keyframes */ } }
Jetzt erhalten Benutzer mit aktivierter reduzierter Bewegung immer noch ein Gefühl für das Erscheinungsbild, jedoch ohne die intensive Bewegung einer Sprung- oder elastischen Animation. Nachdem die Bausteine vorhanden sind, stellt sich als nächstes die Frage, wie sie in den eigentlichen Arbeitsablauf integriert werden können. Flexible Keyframes zu schreiben ist eine Sache, aber um sie in einem großen Projekt zuverlässig zu machen, bedarf es einiger Strategien, die ich mir auf die harte Tour aneignen musste. Implementierungsstrategien und Best Practices Sobald wir über eine solide Bibliothek von Keyframe-Tokens verfügen, besteht die eigentliche Herausforderung darin, diese in die tägliche Arbeit zu integrieren.
Die Versuchung besteht darin, alle Keyframes auf einmal einzufügen und das Problem für gelöst zu erklären, aber in der Praxis habe ich festgestellt, dass die besten Ergebnisse durch eine schrittweise Einführung erzielt werden. Beginnen Sie mit den gängigsten Animationen wie Fade oder Slide. Dies sind einfache Gewinne, die einen sofortigen Wert zeigen, ohne dass große Umschreibungen erforderlich sind. Die Benennung ist ein weiterer Punkt, der Aufmerksamkeit verdient. Ein konsistentes Präfix oder Namespace macht deutlich, welche Animationen Token und welche lokale Einzelstücke sind. Es verhindert außerdem versehentliche Kollisionen und hilft neuen Teammitgliedern, das gemeinsame System auf einen Blick zu erkennen. Die Dokumentation ist genauso wichtig wie der Code selbst. Selbst ein kurzer Kommentar über jedem Keyframe-Token kann später stundenlanges Raten ersparen. Ein Entwickler sollte in der Lage sein, die Tokendatei zu öffnen, nach dem benötigten Effekt zu suchen und das Nutzungsmuster direkt in seine Komponente zu kopieren. Flexibilität macht diesen Ansatz lohnenswert. Durch die Offenlegung sinnvoller benutzerdefinierter Eigenschaften geben wir den Teams Raum, die Animation anzupassen, ohne das System zu beschädigen. Versuchen Sie gleichzeitig, es nicht zu kompliziert zu machen. Stellen Sie die entscheidenden Knöpfe bereit und sorgen Sie dafür, dass der Rest eine Meinung hat. Denken Sie abschließend an die Barrierefreiheit. Nicht jede Animation benötigt eine Alternative mit reduzierter Bewegung, aber viele tun dies. Das frühzeitige Einarbeiten dieser Anpassungen bedeutet, dass wir sie später nie nachrüsten müssen, und es zeigt ein Maß an Sorgfalt, das unsere Benutzer bemerken werden, auch wenn sie es nie erwähnen.
Meiner Erfahrung nach ist die Behandlung von Keyframes-Tokens als Teil unseres Design-Token-Workflows der Grund dafür, dass sie hängen bleiben. Sobald sie angebracht sind, wirken sie nicht mehr wie Spezialeffekte, sondern werden Teil der Designsprache, eine natürliche Erweiterung der Art und Weise, wie sich das Produkt bewegt und reagiert. Zusammenfassung Animationen können einer der unterhaltsamsten Teile beim Erstellen von Schnittstellen sein, aber ohne Struktur können sie auch zu einer der größten Ursachen für Frustration werden. Indem Sie Keyframes als Token behandeln, verwandeln Sie etwas, das normalerweise chaotisch und schwer zu verwalten ist, in ein klares, vorhersehbares System. Der wahre Wert liegt nicht nur darin, ein paar Zeilen Code einzusparen. Wenn Sie Fade, Slide, Zoom oder Spin verwenden, können Sie sicher sein, dass Sie genau wissen, wie es sich im gesamten Projekt verhält. Es liegt in der Flexibilität, die sich aus kundenspezifischen Eigenschaften ergibt, ohne das Chaos endloser Variationen. Und es liegt an der Zugänglichkeit, die in das Fundament integriert und nicht hinzugefügt wurdeein nachträglicher Einfall. Ich habe gesehen, wie diese Ideen in verschiedenen Teams und auf unterschiedlichen Codebasen funktionierten, und das Muster ist immer das gleiche. Sobald die Token vorhanden sind, sind Keyframes keine verstreute Ansammlung von Tricks mehr, sondern Teil der Designsprache. Sie sorgen dafür, dass sich das Produkt bewusster, konsistenter und lebendiger anfühlt. Wenn Sie eines aus diesem Artikel mitnehmen, dann sei es Folgendes: Animationen verdienen die gleiche Sorgfalt und Struktur, die wir bereits Farben, Typografie und Abständen geben. Eine kleine Investition in Keyframes-Tokens zahlt sich jedes Mal aus, wenn sich Ihre Benutzeroberfläche bewegt.