Forestil dig dette: du deltager i et nyt projekt, dykker ned i kodebasen, og inden for de første par timer opdager du noget frustrerende velkendt. Spredt ud over stilarkene finder du flere @keyframes-definitioner for de samme grundlæggende animationer. Tre forskellige fade-in-effekter, to eller tre slide-varianter, en håndfuld zoom-animationer og mindst to forskellige spin-animationer, for ja, hvorfor ikke? @keyframes puls { fra { skala: 1; } til { skala: 1,1; } }

@keyframes bigger-pulse { 0 %, 20 %, 100 % { skala: 1; } 10 %, 40 % { skala: 1,2; } }

Hvis dette scenarie lyder bekendt, er du ikke alene. Efter min erfaring på tværs af forskellige projekter er en af ​​de mest konsekvente hurtige gevinster, jeg kan levere, konsolidering og standardisering af keyframes. Det er blevet så pålideligt et mønster, at jeg nu ser frem til denne oprydning som en af ​​mine første opgaver på en ny kodebase. Logikken bag kaoset Denne redundans giver perfekt mening, når du tænker over det. Vi bruger alle de samme grundlæggende animationer i vores daglige arbejde: fades, dias, zoom, spins og andre almindelige effekter. Disse animationer er ret ligetil, og det er nemt at lave en hurtig @keyframes-definition for at få arbejdet gjort. Uden et centraliseret animationssystem skriver udviklere naturligvis disse keyframes fra bunden, uvidende om, at lignende animationer allerede findes andre steder i kodebasen. Dette er især almindeligt, når man arbejder i komponentbaserede arkitekturer (hvilket de fleste af os gør i dag), da teams ofte arbejder parallelt på tværs af forskellige dele af applikationen. Resultatet? Animation kaos. Det lille problem De mest åbenlyse problemer med duplikering af keyframes er spildte udviklingstid og unødvendig kodeopsvulmning. Flere keyframe-definitioner betyder flere steder at opdatere, når kravene ændres. Har du brug for at justere timingen af ​​din fade-animation? Du bliver nødt til at jage alle forekomster på tværs af din kodebase. Vil du standardisere lempelsesfunktioner? Held og lykke med at finde alle variationerne. Denne multiplikation af vedligeholdelsespunkter gør selv simple animationsopdateringer til en tidskrævende opgave. Det større problem Denne duplikering af keyframes skaber et meget mere lumsk problem, der lurer under overfladen: den globale scope-fælde. Selv når der arbejdes med komponentbaserede arkitekturer, er CSS keyframes altid defineret i det globale omfang. Det betyder, at alle keyframes gælder for alle komponenter. Altid. Ja, din animation bruger ikke nødvendigvis de keyframes, du har defineret i din komponent. Den bruger de sidste keyframes, der matcher nøjagtigt det samme navn, som blev indlæst i det globale omfang. Så længe alle dine keyframes er identiske, kan dette virke som et mindre problem. Men i det øjeblik du ønsker at tilpasse en animation til en bestemt brugssag, er du i problemer, eller endnu værre, du er den, der forårsager dem. Enten virker din animation ikke, fordi en anden komponent indlæst efter din, overskriver dine keyframes, eller også indlæses din komponent sidst og ved et uheld ændrer animationsadfærden for hver anden komponent, der bruger den pågældende keyframes navn, og du er måske ikke engang klar over det. Her er et simpelt eksempel, der viser problemet: .component-one { /* komponent stilarter */ animation: puls 1s ease-in-out uendelig alternativ; }

/* denne @keyframes definition vil ikke fungere */ @keyframes puls { fra { skala: 1; } til { skala: 1,1; } }

/* senere i koden... */

.component-to { /* komponent stilarter */ animation: puls 1s ease-in-out uendelig; }

/* denne keyframes vil gælde for begge komponenter */ @keyframes puls { 0 %, 20 %, 100 % { skala: 1; } 10 %, 40 % { skala: 1,2; } }

Begge komponenter bruger det samme animationsnavn, men den anden @keyframes-definition overskriver den første. Nu vil både komponent-et og komponent-to bruge den anden keyframes, uanset hvilken komponent der definerede hvilke keyframes. Se Pen Keyframes Tokens - Demo 1 [forked] af Amit Sheen. Den værste del? Dette fungerer ofte perfekt i lokal udvikling, men bryder på mystisk vis i produktionen, når byggeprocesser ændrer indlæsningsrækkefølgen af ​​dine stylesheets. Du ender med animationer, der opfører sig forskelligt alt efter hvilke komponenter der er indlæst og i hvilken rækkefølge. Løsningen: Unified Keyframes Svaret på dette kaos er overraskende enkelt: foruddefinerede dynamiske keyframes gemt i et delt stylesheet. I stedet for at lade hver komponent definere sine egne animationer, skaber vi centraliserede keyframes, der er veldokumenterede, nemme atbruge, vedligeholdes og skræddersyet til dit projekts specifikke behov. Tænk på det som keyframes-tokens. Ligesom vi bruger tokens til farver og mellemrum, og mange af os allerede bruger tokens til animationsegenskaber, såsom varighed og lette funktioner, hvorfor så ikke også bruge tokens til keyframes? Denne tilgang kan integreres naturligt med enhver aktuel designtoken-workflow, du bruger, mens du løser både det lille problem (kodeduplikering) og det større problem (konflikter med globalt omfang) på én gang. Ideen er ligetil: Skab en enkelt kilde til sandhed for alle vores fælles animationer. Dette delte stylesheet indeholder omhyggeligt udformede keyframes, der dækker de animationsmønstre, vores projekt faktisk bruger. Ikke mere at gætte på, om en fade-animation allerede eksisterer et sted i vores kodebase. Ikke mere utilsigtet overskrivning af animationer fra andre komponenter. Men her er nøglen: disse er ikke kun statiske copy-paste-animationer. De er designet til at være dynamiske og kan tilpasses gennem brugerdefinerede CSS-egenskaber, hvilket giver os mulighed for at opretholde konsistens, mens vi stadig har fleksibiliteten til at tilpasse animationer til specifikke brugssager, som hvis du har brug for en lidt større "puls"-animation ét sted. Opbygning af det første keyframes-token En af de første lavthængende frugter, vi bør tage fat på, er "fade-in"-animationen. I et af mine seneste projekter fandt jeg over et dusin separate fade-in definitioner, og ja, de animerede alle simpelthen opaciteten fra 0 til 1. Så lad os oprette et nyt stylesheet, kalde det kf-tokens.css, importere det til vores projekt og placere vores keyframes med de rigtige kommentarer inde i det. /* keyframes-tokens.css */

/* * Fade In - fade indgangsanimation * Anvendelse: animation: kf-fade-in 0.3s ease-out; */ @keyframes kf-fade-in { fra { opacitet: 0; } til { opacitet: 1; } }

Denne enkelte @keyframes-erklæring erstatter alle de spredte fade-in-animationer på tværs af vores kodebase. Ren, enkel og globalt anvendelig. Og nu hvor vi har defineret dette token, kan vi bruge det fra enhver komponent i hele vores projekt: .modal { animation: kf-fade-in 0.3s ease-out; }

.værktøjstip { animation: kf-fade-in 0.2s lethed-in-out; }

.notification { animation: kf-fade-in 0,5s ease-out; }

Se Pen Keyframes Tokens - Demo 2 [forked] af Amit Sheen. Bemærk: Vi bruger et kf-præfiks i alle vores @keyframes-navne. Dette præfiks fungerer som et navneområde, der forhindrer navnekonflikter med eksisterende animationer i projektet og gør det umiddelbart klart, at disse keyframes kommer fra vores keyframes-tokens-fil. Lav et dynamisk dias Kf-fade-in keyframes fungerer godt, fordi det er enkelt, og der er lidt plads til at rode ting op. I andre animationer skal vi dog være meget mere dynamiske, og her kan vi udnytte den enorme kraft i CSS-tilpassede egenskaber. Det er her keyframes-tokens virkelig skinner sammenlignet med spredte statiske animationer. Lad os tage et almindeligt scenarie: "slide-in"-animationer. Men glide ind fra hvor? 100px fra højre? 50% fra venstre? Skal det ind fra toppen af ​​skærmen? Eller måske flyde ind fra bunden? Så mange muligheder, men i stedet for at skabe separate keyframes for hver retning og hver variation, kan vi bygge et fleksibelt token, der tilpasser sig alle scenarier: /* * Slide In - retningsbestemt slide-animation * Brug --kf-slide-fra for at styre retningen * Standard: glider ind fra venstre (-100%) *Anvendelse: * animation: kf-slide-in 0.3s ease-out; * --kf-slide-fra: -100px 0; // glid fra venstre * --kf-slide-from: 100px 0; // glid fra højre * --kf-slide-fra: 0 -50px; // slide fra toppen */

@keyframes kf-slide-in { fra { oversæt: var(--kf-slide-fra, -100% 0); } til { oversæt: 0 0; } }

Nu kan vi bruge dette enkelte @keyframes-token til enhver diasretning ved blot at ændre egenskaben --kf-slide-from custom: .sidebar { animation: kf-slide-in 0.3s ease-out; /* Bruger standardværdi: slides fra venstre */ }

.notification { animation: kf-slide-in 0,4s ease-out; --kf-slide-fra: 0 -50px; /* slide fra toppen */ }

.modal { animation: kf-fade-in 0,5s, kf-slide-in 0,5s cubic-bezier(0,34, 1,56, 0,64, 1); --kf-slide-from: 50px 50px; /* slide fra nederst til højre */ }

Denne tilgang giver os utrolig fleksibilitet, samtidig med at vi bevarer konsistensen. Én keyframe-erklæring, uendelige muligheder. Se Pen Keyframes Tokens - Demo 3 [forked] af Amit Sheen. Og hvis vi ønsker at gøre vores animationer endnu mere fleksible og også give mulighed for "slide-out" effekter, kan viblot tilføje en --kf-slide-to brugerdefineret egenskab, svarende til hvad vi vil se i næste afsnit. Tovejs zoom nøglerammer En anden almindelig animation, der bliver duplikeret på tværs af projekter, er "zoom"-effekter. Uanset om det er en subtil opskalering for toast-beskeder, en dramatisk zoom-ind for modaler eller en blid nedskaleringseffekt for overskrifter, er zoom-animationer overalt. I stedet for at oprette separate keyframes for hver skalaværdi, lad os bygge ét fleksibelt sæt kf-zoom keyframes:

/* * Zoom - skala animation * Brug --kf-zoom-from og --kf-zoom-to til at styre skalaværdier * Standard: zoomer fra 80 % til 100 % (0,8 til 1) *Anvendelse: * animation: kf-zoom 0.2s ease-out; * --kf-zoom-fra: 0,5; --kf-zoom-to: 1; // zoom fra 50 % til 100 % * --kf-zoom-fra: 1; --kf-zoom-to: 0; // zoom fra 100 % til 0 % * --kf-zoom-fra: 1; --kf-zoom-to: 1.1; // zoom fra 100 % til 110 % */

@keyframes kf-zoom { fra { skala: var(--kf-zoom-fra, 0,8); } til { skala: var(--kf-zoom-to, 1); } }

Med én definition kan vi opnå enhver zoomvariation, vi har brug for: .toast { animation: kf-slide-in 0,2s, kf-zoom 0,4s ease-out; --kf-slide-fra: 0 100%; /* slide fra toppen */ /* Bruger standardzoom: skalerer fra 80 % til 100 % */ }

.modal { animation: kf-zoom 0,3s cubic-bezier(0,34, 1,56, 0,64, 1); --kf-zoom-fra: 0; /* dramatisk zoom fra 0 % til 100 % */ }

.heading { animation: kf-fade-in 2s, kf-zoom 2s let ind; --kf-zoom-fra: 1,2; --kf-zoom-to: 0,8; /* blid nedskalering */ }

Standarden på 0,8 (80 %) fungerer perfekt til de fleste UI-elementer, såsom toast-beskeder og kort, mens den stadig er nem at tilpasse til særlige tilfælde. Se Pen Keyframes Tokens - Demo 4 [forked] af Amit Sheen. Du har måske bemærket noget interessant i de seneste eksempler: vi har kombineret animationer. En af de vigtigste fordele ved at arbejde med @keyframes-tokens er, at de er designet til at integreres problemfrit med hinanden. Denne glatte sammensætning er bevidst, ikke tilfældig. Vi vil diskutere animationssammensætning mere detaljeret senere, herunder hvor de kan blive problematiske, men de fleste kombinationer er ligetil og nemme at implementere. Bemærk: Mens jeg skrev denne artikel, og måske på grund af at skrive den, fandt jeg mig selv i at gentænke hele ideen med indgangsanimationer. Med alle de seneste fremskridt inden for CSS, har vi overhovedet brug for dem? Heldigvis udforskede Adam Argyle de samme spørgsmål og udtrykte dem glimrende i sin blog. Dette modsiger ikke, hvad der er skrevet her, men det præsenterer en tilgang, der er værd at overveje, især hvis dine projekter er stærkt afhængige af indgangsanimationer. Kontinuerlige animationer Mens indgangsanimationer, som "fade", "slide" og "zoom" sker én gang og derefter stopper, løber kontinuerlige animationer uendeligt for at tiltrække opmærksomhed eller angive igangværende aktivitet. De to mest almindelige kontinuerlige animationer, jeg støder på, er "spin" (til indlæsningsindikatorer) og "puls" (til at fremhæve vigtige elementer). Disse animationer giver unikke udfordringer, når det kommer til at skabe keyframes-tokens. I modsætning til indgangsanimationer, der typisk går fra en tilstand til en anden, skal kontinuerlige animationer være meget tilpasselige i deres adfærdsmønstre. Spindoktoren Hvert projekt ser ud til at bruge flere spin-animationer. Nogle drejer med uret, andre mod uret. Nogle laver en enkelt 360-graders rotation, andre laver flere drejninger for en hurtigere effekt. I stedet for at skabe separate keyframes for hver variant, lad os bygge ét fleksibelt spin, der håndterer alle scenarier:

/* * Spin - rotationsanimation * Brug --kf-spin-from og --kf-spin-to til at styre rotationsområdet * Brug --kf-spin-turns til at kontrollere rotationsmængden * Standard: roterer fra 0 grader til 360 grader (1 fuld rotation) *Anvendelse: * animation: kf-spin 1s lineær uendelig; * --kf-spin-drejninger: 2; // 2 hele omdrejninger * --kf-spin-fra: 0 grader; --kf-spin-to: 180 grader; // halv rotation * --kf-spin-fra: 0 grader; --kf-spin-to: -360 grader; // mod uret */

@keyframes kf-spin { fra { rotere: var(--kf-spin-fra, 0 grader); } til { roter: calc(var(--kf-spin-fra, 0deg) + var(--kf-spin-to, 360deg) * var(--kf-spin-drejninger, 1)); } }

Nu kan vi oprette enhver spin-variation, vi kan lide:

.loading-spinner { animation: kf-spin 1s lineær uendelig; /* Bruger standard: roterer fra 0deg til 360deg */ }

.fast-loader { animation: kf-spin 1.2s ease-in-out uendelig alternativ; --kf-spin-vender: 3; /* 3 hele rotationer for hver retning pr. cyklus*/ }

.steped-reverse { animation: kf-spin 1.5s trin(8) uendelig; --kf-spin-to: -360 grader; /* mod uret */ }

.subtle-wiggle { animation: kf-spin 2s let-ind-ud uendelig alternativ; --kf-spin-fra: -16 grader; --kf-spin-to: 32 grader; /* vrikke 36 grader: mellem -18 grader og +18 grader */ }

Se Pen Keyframes Tokens - Demo 5 [forked] af Amit Sheen. Skønheden ved denne tilgang er, at de samme keyframes fungerer til at indlæse spinnere, roterende ikoner, vrikkeeffekter og endda komplekse multi-turn-animationer. Pulsparadokset Pulsanimationer er vanskeligere, fordi de kan "pulsere" forskellige egenskaber. Nogle pulserer skalaen, andre pulserer opaciteten, og nogle pulserer farveegenskaber som lysstyrke eller mætning. I stedet for at oprette separate keyframes for hver ejendom, kan vi oprette keyframes, der fungerer med enhver CSS-ejendom. Her er et eksempel på en pulskeyframe med skala- og opacitetsindstillinger:

/* * Puls - pulserende animation * Brug --kf-pulse-scale-fra og --kf-pulse-scale-to til at styre skalaområdet * Brug --kf-pulse-opacity-from og --kf-pulse-opacity-to til at styre opacitetsområdet * Standard: ingen puls (alle værdier 1) *Anvendelse: * animation: kf-puls 2s let-ind-ud uendelig alternativ; * --kf-pulsskala-fra: 0,95; --kf-pulsskala-til: 1,05; // skala puls * --kf-pulsopacitet-fra: 0,7; --kf-puls-opacitet-til: 1; // opacitetspuls */

@keyframes kf-puls { fra { skala: var(--kf-puls-skala-fra, 1); opacitet: var(--kf-puls-opacitet-fra, 1); } til { skala: var(--kf-puls-skala-til, 1); opacitet: var(--kf-puls-opacitet-til, 1); } }

Dette skaber en fleksibel puls, der kan animere flere egenskaber: .call-to-action { animation: kf-puls 0,6s uendelig alternativ; --kf-pulsopacitet-fra: 0,5; /* opacitetspuls */ }

.notification-dot { animation: kf-puls 0.6s ease-in-out uendelig alternativ; --kf-pulsskala-fra: 0,9; --kf-puls-skala-til: 1,1; /* skala puls */ }

.text-highlight { animation: kf-puls 1.5s ease-out uendelig; --kf-pulsskala-fra: 0,8; --kf-pulsopacitet-fra: 0,2; /* skala og opacitetspuls */ }

Se Pen Keyframes Tokens - Demo 6 [forked] af Amit Sheen. Denne enkelte kf-puls keyframe kan håndtere alt fra subtile opmærksomhedsgreb til dramatiske højdepunkter, alt imens den er nem at tilpasse. Avanceret lempelse En af de fantastiske ting ved at bruge keyframes-tokens er, hvor nemt det er at udvide vores animationsbibliotek og levere effekter, som de fleste udviklere ikke gider at skrive fra bunden, såsom elastik eller bounce. Her er et eksempel på et simpelt "bounce" keyframes-token, der bruger en --kf-bounce-from tilpasset egenskab til at kontrollere springhøjden. /* * Bounce - hoppende indgangsanimation * Brug --kf-bounce-from til at kontrollere springhøjden * Standard: hopper fra 100vh (fra skærm) *Anvendelse: * animation: kf-bounce 3s ease-in; * --kf-bounce-from: 200px; // hop fra 200px højde */

@keyframes kf-bounce { 0 % { translate: 0 calc(var(--kf-bounce-from, 100vh) * -1); }

34 % { translate: 0 calc(var(--kf-bounce-from, 100vh) * -0,4); }

55 % { translate: 0 calc(var(--kf-bounce-from, 100vh) * -0,2); }

72 % { translate: 0 calc(var(--kf-bounce-from, 100vh) * -0.1); }

85 % { translate: 0 calc(var(--kf-bounce-from, 100vh) * -0,05); }

94 % { translate: 0 calc(var(--kf-bounce-from, 100vh) * -0,025); }

99 % { translate: 0 calc(var(--kf-bounce-from, 100vh) * -0,0125); }

22 %, 45 %, 64 %, 79 %, 90 %, 97 %, 100 % { oversæt: 0 0; animation-timing-funktion: ease-out; } }

Animationer som "elastisk" er lidt vanskeligere på grund af beregningerne inde i keyframes. Vi skal definere --kf-elastic-fra-X og --kf-elastic-from-Y separat (begge er valgfrie), og sammen lader de os skabe en elastisk indgang fra ethvert punkt på skærmen.

/* * Elastic In - elastisk indgangsanimation * Brug --kf-elastic-from-X og --kf-elastic-from-Y til at styre startpositionen * Standard: går ind fra øverste center (0, -100vh) *Anvendelse: * animation: kf-elastic-in 2s ease-in-out begge dele; * --kf-elastic-fra-X: -50px; * --kf-elastic-fra-Y: -200px; // indtast fra (-50px, -200px) */

@keyframes kf-elastic-in { 0 % { translate: calc(var(--kf-elastic-fra-X, -50vw) * 1) calc(var(--kf-elastic-fra-Y, 0px) * 1); }

16 % { translate: calc(var(--kf-elastic-fra-X, -50vw) * -0,3227) calc(var(--kf-elastic-fra-Y, 0px) * -0,3227); }

28 % { oversæt: calc(var(--kf-elastic-fra-X, -50vw) * 0,1312)beregnet(var(--kf-elastik-fra-Y, 0px) * 0,1312); }

44 % { oversæt: calc(var(--kf-elastic-fra-X, -50vw) * -0,0463) calc(var(--kf-elastic-fra-Y, 0px) * -0,0463); }

59 % { translate: calc(var(--kf-elastic-fra-X, -50vw) * 0,0164) calc(var(--kf-elastic-fra-Y, 0px) * 0,0164); }

73 % { oversæt: calc(var(--kf-elastic-fra-X, -50vw) * -0,0058) calc(var(--kf-elastic-fra-Y, 0px) * -0,0058); }

88 % { oversæt: calc(var(--kf-elastic-fra-X, -50vw) * 0,0020) calc(var(--kf-elastic-fra-Y, 0px) * 0,0020); }

100 % { oversæt: 0 0; } }

Denne tilgang gør det nemt at genbruge og tilpasse avancerede keyframes på tværs af vores projekt, blot ved at ændre en enkelt tilpasset egenskab.

.bounce-and-zoom { animation: kf-bounce 3s ease-in, kf-zoom 3s lineær; --kf-zoom-fra: 0; }

.bounce-and-slide { animation-komposition: tilføje; /* Begge animationer bruger translate */ animation: kf-bounce 3s ease-in, kf-slide-in 3s ease-out; --kf-slide-fra: -200px; }

.elastic-in { animation: kf-elastic-in 2s ease-in-out begge dele; }

Se Pen Keyframes Tokens - Demo 7 [forked] af Amit Sheen. Indtil nu har vi set, hvordan vi kan konsolidere keyframes på en smart og effektiv måde. Selvfølgelig vil du måske justere tingene, så de passer bedre til dit projekts behov, men vi har dækket eksempler på flere almindelige animationer og hverdagsbrug. Og med disse keyframes-tokens på plads, har vi nu kraftfulde byggeklodser til at skabe ensartede, vedligeholdelige animationer på tværs af hele projektet. Ikke flere duplikerede keyframes, ikke flere globale omfangskonflikter. Bare en ren, bekvem måde at håndtere alle vores animationsbehov. Men det egentlige spørgsmål er: Hvordan komponerer vi disse byggeklodser sammen? At sætte det hele sammen Vi har set, at det er enkelt at kombinere grundlæggende keyframes-tokens. Vi behøver ikke noget særligt end at definere den første animation, definere den anden, indstille variablerne efter behov, og det er det. /* Fade in + slide in */ .toast { animation: kf-fade-in 0,4s, kf-slide-in 0,4s cubic-bezier(0,34, 1,56, 0,64, 1); --kf-slide-fra: 0 40px; }

/* Zoom ind + fade ind */ .modal { animation: kf-fade-in 0,3s, kf-zoom 0,3s cubic-bezier(0,34, 1,56, 0,64, 1); --kf-zoom-fra: 0,7; --kf-zoom-to: 1; }

/* Skub ind + puls */ .notification { animation: kf-slide-in 0,5s, kf-puls 1.2s ease-in-out uendelig alternativ; --kf-slide-fra: -100px 0; --kf-pulsskala-fra: 0,95; --kf-pulsskala-til: 1,05; }

Disse kombinationer fungerer smukt, fordi hver animation retter sig mod en anden egenskab: opacitet, transformation (oversæt/skaler) osv. Men nogle gange er der konflikter, og vi skal vide hvorfor og hvordan vi skal håndtere dem. Når to animationer forsøger at animere den samme egenskab - for eksempel begge animationsskalaer eller begge animerende opacitet - bliver resultatet ikke, hvad du forventer. Som standard er kun én af animationerne faktisk anvendt på den pågældende egenskab, som er den sidste på animationslisten. Dette er en begrænsning af, hvordan CSS håndterer flere animationer på den samme ejendom. For eksempel vil dette ikke fungere efter hensigten, fordi kun kf-puls-animationen vil gælde. .bad-combo { animation: kf-zoom 0,5s fremad, kf-puls 1.2s uendelig alternerende; --kf-zoom-fra: 0,5; --kf-zoom-to: 1,2; --kf-pulsskala-fra: 0,8; --kf-puls-skala-til: 1,1; }

Animation tilføjelse Den enkleste og mest direkte måde at håndtere flere animationer, der påvirker den samme egenskab, er at bruge egenskaben animation-composition. I det sidste eksempel ovenfor erstatter kf-puls-animationen kf-zoom-animationen, så vi vil ikke se den indledende zoom og vil ikke få den forventede skala til 1,2. Ved at indstille den animation-sammensætning, der skal tilføjes, fortæller vi browseren at kombinere begge animationer. Dette giver os det resultat, vi ønsker. .component-to { animation-komposition: tilføje; }

Se Pen Keyframes Tokens - Demo 8 [forked] af Amit Sheen. Denne tilgang fungerer godt i de fleste tilfælde, hvor vi ønsker at kombinere effekter på den samme ejendom. Det er også nyttigt, når vi skal kombinere animationer med statiske egenskabsværdier. For eksempel, hvis vi har et element, der bruger translate-egenskaben til at placere det præcis, hvor vi vil, og så vil vi animere det med kf-slide-in keyframes, får vi et grimt synligt hop uden animationskomposition. Se Pen Keyframes Tokens - Demo 9 [forked] af Amit Sheen. Med animation-komposition indstillet til at tilføje, kombineres animationen glat med det eksisterendetransformere, så elementet bliver på plads og animerer som forventet. Animation Stagger En anden måde at håndtere flere animationer på er at "forskyde" dem - det vil sige at starte den anden animation lidt efter, at den første er færdig. Det er ikke en løsning, der fungerer for alle tilfælde, men det er nyttigt, når vi har en indgangsanimation efterfulgt af en kontinuerlig animation. /* fade in + opacitetspuls */ .notification { animation: kf-fade-in 2s ease-out, kf-puls 0,5s 2s let-ind-ud uendelig alternativ; --kf-puls-opacitet-til: 0,5; }

Se Pen Keyframes Tokens - Demo 10 [forked] af Amit Sheen. Orden har betydning En stor del af de animationer, vi arbejder med, bruger transform-egenskaben. I de fleste tilfælde er dette simpelthen mere bekvemt. Det har også en ydeevnefordel, da transformationsanimationer kan GPU-accelereres. Men hvis vi bruger transformationer, er vi nødt til at acceptere, at den rækkefølge, vi udfører vores transformationer i, har betydning. En masse. I vores keyframes har vi hidtil brugt individuelle transformationer. Ifølge specifikationerne anvendes disse altid i en fast rækkefølge: først bliver elementet oversat, derefter roteret og derefter skaleret. Dette giver mening og er, hvad de fleste af os forventer. Men hvis vi bruger transformegenskaben, er den rækkefølge, som funktionerne skrives i, den rækkefølge, de anvendes i. I dette tilfælde, hvis vi flytter noget 100 pixels på X-aksen og derefter roterer det 45 grader, er det ikke det samme som først at rotere det 45 grader og derefter flytte det 100 pixels. /* Lyserød firkant: Oversæt først, drej derefter */ .example-one { transform: translateX(100px) rotate(45deg); }

/* Grøn firkant: Roter først, og oversæt derefter */ .example-two { transform: rotate(45deg) translateX(100px); }

Se Pen Keyframes Tokens - Demo 11 [forked] af Amit Sheen. Men ifølge transformationsrækkefølgen sker alle individuelle transformationer - alt hvad vi har brugt til keyframes-tokens - før transformationsfunktionerne. Det betyder, at alt, hvad du indstiller i transformationsegenskaben, vil ske efter animationerne. Men hvis du for eksempel indstiller oversæt sammen med kf-spin keyframes, vil oversættelsen ske før animationen. Endnu forvirret?! Dette fører til situationer, hvor statiske værdier kan forårsage forskellige resultater for den samme animation, som i følgende tilfælde:

/* Fælles animation for begge spinnere */ .spinner { animation: kf-spin 1s lineær uendelig; }

/* Pink spinner: oversæt før rotation (individuel transformation) */ .spinner-pink { oversæt: 100% 50%; }

/* Grøn spinner: roter og oversæt derefter (funktionsrækkefølge) */ .spinner-green { transform: translate(100%, 50%); }

Se Pen Keyframes Tokens - Demo 12 [forked] af Amit Sheen. Du kan se, at den første spinner (pink) får en translate, der sker før rotationen af ​​kf-spin, så den først flytter til sin plads og derefter spins. Den anden spinner (grøn) får en translate() funktion, der sker efter den individuelle transformation, så elementet roterer først og bevæger sig derefter i forhold til sin nuværende vinkel, og vi får den brede kredsløbseffekt. Nej, dette er ikke en fejl. Det er blot en af ​​de ting, vi skal vide om CSS og huske på, når vi arbejder med flere animationer eller flere transformationer. Hvis det er nødvendigt, kan du også oprette et ekstra sæt kf-spin-alt keyframes, der roterer elementer ved hjælp af rotate()-funktionen. Reduceret bevægelse Og mens vi taler om alternative keyframes, kan vi ikke ignorere muligheden "ingen animation". En af de største fordele ved at bruge keyframes-tokens er, at tilgængelighed kan bages ind, og det er faktisk ret nemt at gøre. Ved at designe vores keyframes med tilgængelighed i tankerne kan vi sikre, at brugere, der foretrækker reduceret bevægelse, får en mere jævn, mindre distraherende oplevelse uden ekstra arbejde eller kodeduplikering. Den nøjagtige betydning af "Reduced Motion" kan ændre sig en smule fra en animation til en anden og fra projekt til projekt, men her er et par vigtige punkter at huske på: Deaktivering af keyframes Mens nogle animationer kan blødgøres eller bremses, er der andre, der burde forsvinde fuldstændigt, når der anmodes om reduceret bevægelse. Pulsanimationer er et godt eksempel. For at sikre, at disse animationer ikke kører i reduceret bevægelsestilstand, kan vi blot pakke dem ind i den relevante medieforespørgsel.

@media (prefers-reduced-motion: no-preference) { @keyfrmaes kf-pulse { fra { skala: var(--kf-puls-skala-fra, 1); opacitet: var(--kf-puls-opacitet-fra, 1); } til { skala: var(--kf-puls-skala-til, 1); opacitet:var(--kf-puls-opacitet-til, 1); } } }

Dette sikrer, at brugere, der har indstillet foretrækker-reduceret-bevægelse til at reducere, ikke vil se animationen og vil få en oplevelse, der matcher deres præference. Øjeblikkelig ind Der er nogle keyframes, vi ikke bare kan fjerne, såsom indgangsanimationer. Værdien skal ændre sig, skal animere; ellers vil elementet ikke have de korrekte værdier. Men i reduceret bevægelse bør denne overgang fra startværdien være øjeblikkelig. For at opnå dette definerer vi et ekstra sæt nøglerammer, hvor værdien straks springer til sluttilstanden. Disse bliver vores standard keyframes. Derefter tilføjer vi de almindelige keyframes i en medieforespørgsel for prefers-reduced-motion sat til no-preference, ligesom i det forrige eksempel. /* pop ind med det samme for at reducere bevægelse */ @keyframes kf-zoom { fra, til { skala: var(--kf-zoom-to, 1); } }

@media (prefers-reduced-motion: no-preference) { /* Originale zoom keyframes */ @keyframes kf-zoom { fra { skala: var(--kf-zoom-fra, 0,8); } til { skala: var(--kf-zoom-to, 1); } } }

På denne måde vil brugere, der foretrækker reduceret bevægelse, se elementet vises øjeblikkeligt i sin endelige tilstand, mens alle andre får den animerede overgang. Den bløde tilgang Der er tilfælde, hvor vi gerne vil holde lidt bevægelse, men meget blødere og roligere end den originale animation. For eksempel kan vi erstatte en hoppeindgang med en blid fade-in.

@keyframes kf-bounce { /* Blød fade-in for reduceret bevægelse */ }

@media (prefers-reduced-motion: no-preference) { @keyframes kf-bounce { /* Originale bounce keyframes */ } }

Nu får brugere med reduceret bevægelse aktiveret stadig en følelse af udseende, men uden den intense bevægelse af et spring eller elastisk animation. Med byggeklodserne på plads er det næste spørgsmål, hvordan man gør dem til en del af selve arbejdsgangen. At skrive fleksible keyframes er én ting, men at gøre dem pålidelige på tværs af et stort projekt kræver et par strategier, som jeg skulle lære på den hårde måde. Implementeringsstrategier og bedste praksis Når vi først har et solidt bibliotek af keyframes-tokens, er den virkelige udfordring, hvordan vi bringer dem ind i det daglige arbejde.

Fristelsen er at droppe alle keyframes på én gang og erklære problemet løst, men i praksis har jeg fundet ud af, at de bedste resultater kommer fra gradvis adoption. Start med de mest almindelige animationer, såsom fade eller slide. Disse er nemme gevinster, der viser øjeblikkelig værdi uden at kræve store omskrivninger. Navngivning er et andet punkt, der fortjener opmærksomhed. Et konsekvent præfiks eller navneområde gør det indlysende, hvilke animationer der er tokens, og hvilke der er lokale engangselementer. Det forhindrer også utilsigtede kollisioner og hjælper nye teammedlemmer med at genkende det delte system med et øjeblik. Dokumentation er lige så vigtig som selve koden. Selv en kort kommentar over hvert keyframe-token kan spare timers gættetid senere. En udvikler bør være i stand til at åbne tokens-filen, scanne for den effekt, de har brug for, og kopiere brugsmønsteret direkte ind i deres komponent. Fleksibilitet er det, der gør denne tilgang umagen værd. Ved at eksponere fornuftige brugerdefinerede egenskaber giver vi teams plads til at tilpasse animationen uden at ødelægge systemet. Prøv samtidig ikke at overkomplicere. Sørg for de knapper, der betyder noget, og hold resten orienteret. Husk endelig tilgængelighed. Ikke enhver animation har brug for et reduceret bevægelsesalternativ, men mange gør det. At bage disse justeringer tidligt betyder, at vi aldrig behøver at eftermontere dem senere, og det viser et niveau af omhu, som vores brugere vil bemærke, selvom de aldrig nævner det.

Efter min erfaring er det at behandle keyframes-tokens som en del af vores design-tokens-workflow, hvad der får dem til at hænge fast. Når de først er på plads, holder de op med at føle sig som specielle effekter og bliver en del af designsproget, en naturlig forlængelse af, hvordan produktet bevæger sig og reagerer. Indpakning Animationer kan være en af de mest glædelige dele af at bygge grænseflader, men uden struktur kan de også blive en af de største kilder til frustration. Ved at behandle keyframes som tokens tager du noget, der normalt er rodet og svært at administrere, og gør det til et klart, forudsigeligt system. Den reelle værdi ligger ikke kun i at gemme et par linjer kode. Det er i tillid til, at når du bruger en fade, dias, zoom eller spin, ved du præcis, hvordan den vil opføre sig på tværs af projektet. Det er i fleksibiliteten, der kommer fra brugerdefinerede egenskaber uden kaos af endeløse variationer. Og det er i tilgængeligheden indbygget i fundamentet frem for tilføjet somen eftertanke. Jeg har set disse ideer fungere i forskellige teams og forskellige kodebaser, og mønsteret er altid det samme. Når tokens først er på plads, holder keyframes op med at være en spredt samling af tricks og bliver en del af designsproget. De får produktet til at føles mere tilsigtet, mere konsistent og mere levende. Hvis du tager én ting fra denne artikel, så lad det være dette: animationer fortjener den samme pleje og struktur, som vi allerede giver til farver, typografi og mellemrum. En lille investering i keyframes-tokens betaler sig, hver gang din grænseflade bevæger sig.

You May Also Like

Enjoyed This Article?

Get weekly tips on growing your audience and monetizing your content — straight to your inbox.

No spam. Join 138,000+ creators. Unsubscribe anytime.

Create Your Free Bio Page

Join 138,000+ creators on Seemless.

Get Started Free