Stel je dit voor: je sluit je aan bij een nieuw project, duikt in de codebase en binnen de eerste paar uur ontdek je iets frustrerend bekends. Verspreid over de stylesheets vindt u meerdere @keyframes-definities voor dezelfde basisanimaties. Drie verschillende fade-in-effecten, twee of drie diavariaties, een handvol zoomanimaties en minstens twee verschillende spin-animaties, want waarom niet? @keyframes puls { van { schaal: 1; } naar { schaal: 1,1; } }

@keyframes grotere puls { 0%, 20%, 100% { schaal: 1; } 10%, 40% { schaal: 1,2; } }

Als dit scenario bekend klinkt, ben je niet de enige. In mijn ervaring met verschillende projecten is het consolideren en standaardiseren van keyframes een van de meest consistente quick wins die ik kan realiseren. Het is zo’n betrouwbaar patroon geworden dat ik nu uitkijk naar deze opruiming als een van mijn eerste taken op een nieuwe codebase. De logica achter de chaos Deze redundantie is volkomen logisch als je erover nadenkt. We gebruiken allemaal dezelfde fundamentele animaties in ons dagelijks werk: fades, slides, zooms, spins en andere veel voorkomende effecten. Deze animaties zijn vrij eenvoudig en het is gemakkelijk om snel een @keyframes-definitie op te stellen om de klus te klaren. Zonder een gecentraliseerd animatiesysteem schrijven ontwikkelaars deze keyframes uiteraard helemaal opnieuw, zich er niet van bewust dat vergelijkbare animaties elders in de codebase al bestaan. Dit komt vooral veel voor bij het werken in componentgebaseerde architecturen (wat de meesten van ons tegenwoordig doen), omdat teams vaak parallel werken in verschillende delen van de applicatie. Het resultaat? Animatiechaos. Het kleine probleem De meest voor de hand liggende problemen met het dupliceren van sleutelframes zijn verspilde ontwikkeltijd en onnodige codezwelling. Meerdere sleutelframedefinities betekenen dat er meerdere plaatsen moeten worden bijgewerkt wanneer de vereisten veranderen. Wilt u de timing van uw fade-animatie aanpassen? U moet elke instantie in uw codebase opsporen. Wilt u versoepelingsfuncties standaardiseren? Veel succes met het vinden van alle varianten. Deze vermenigvuldiging van onderhoudspunten maakt zelfs eenvoudige animatie-updates een tijdrovende taak. Het grotere probleem Deze duplicatie van sleutelframes creëert een veel verraderlijker probleem dat onder de oppervlakte op de loer ligt: de mondiale scopevalkuil. Zelfs als er met componentgebaseerde architecturen wordt gewerkt, worden CSS-keyframes altijd gedefinieerd in het globale bereik. Dit betekent dat alle keyframes van toepassing zijn op alle componenten. Altijd. Ja, uw animatie maakt niet noodzakelijkerwijs gebruik van de hoofdframes die u in uw component heeft gedefinieerd. Het gebruikt de laatste keyframes die overeenkomen met exact dezelfde naam en die in het globale bereik zijn geladen. Zolang al uw keyframes identiek zijn, lijkt dit misschien een klein probleem. Maar op het moment dat je een animatie wilt aanpassen voor een specifiek gebruik, kom je in de problemen, of erger nog, jij bent degene die de problemen veroorzaakt. Ofwel werkt uw animatie niet omdat een andere component na de uwe wordt geladen, waardoor uw hoofdframes worden overschreven, ofwel uw component wordt als laatste geladen en verandert per ongeluk het animatiegedrag voor elke andere component die de naam van dat sleutelframe gebruikt, zonder dat u zich dat eens realiseert. Hier is een eenvoudig voorbeeld dat het probleem laat zien: .component-één { /* componentstijlen */ animatie: puls 1s gemak-in-uit oneindig afwisselend; }

/* deze @keyframes-definitie werkt niet */ @keyframes puls { van { schaal: 1; } naar { schaal: 1,1; } }

/* verderop in de code... */

.component-twee { /* componentstijlen */ animatie: puls 1s gemak-in-uit oneindig; }

/* deze keyframes zijn van toepassing op beide componenten */ @keyframes puls { 0%, 20%, 100% { schaal: 1; } 10%, 40% { schaal: 1,2; } }

Beide componenten gebruiken dezelfde animatienaam, maar de tweede @keyframes-definitie overschrijft de eerste. Nu zullen zowel component één als component twee de tweede keyframes gebruiken, ongeacht welke component welke keyframes heeft gedefinieerd. Bekijk de Pen Keyframes Tokens - Demo 1 [gevorkt] door Amit Sheen. Het ergste? Dit werkt vaak perfect bij lokale ontwikkeling, maar breekt op mysterieuze wijze tijdens de productie wanneer bouwprocessen de laadvolgorde van uw stylesheets veranderen. Je krijgt animaties die zich anders gedragen, afhankelijk van welke componenten worden geladen en in welke volgorde. De oplossing: uniforme sleutelframes Het antwoord op deze chaos is verrassend eenvoudig: vooraf gedefinieerde dynamische keyframes opgeslagen in een gedeeld stylesheet. In plaats van elke component zijn eigen animaties te laten definiëren, creëren we gecentraliseerde keyframes die goed gedocumenteerd en gemakkelijk te gebruiken zijngebruiksvriendelijk, onderhoudbaar en afgestemd op de specifieke behoeften van uw project. Zie het als keyframes-tokens. Net zoals we tokens gebruiken voor kleuren en spatiëring, en velen van ons al tokens gebruiken voor animatie-eigenschappen, zoals duur- en versnellingsfuncties, waarom zouden we dan ook geen tokens gebruiken voor keyframes? Deze aanpak kan op natuurlijke wijze worden geïntegreerd met elke huidige ontwerptokenworkflow die u gebruikt, terwijl u zowel het kleine probleem (codeduplicatie) als het grotere probleem (globale scopeconflicten) in één keer oplost. Het idee is eenvoudig: creëer één enkele bron van waarheid voor al onze gemeenschappelijke animaties. Dit gedeelde stylesheet bevat zorgvuldig vervaardigde keyframes die de animatiepatronen bestrijken die ons project daadwerkelijk gebruikt. U hoeft niet meer te raden of er ergens in onze codebase al een fade-animatie bestaat. Nooit meer per ongeluk animaties van andere componenten overschrijven. Maar hier is de sleutel: dit zijn niet alleen statische kopieer-plakanimaties. Ze zijn ontworpen om dynamisch en aanpasbaar te zijn via aangepaste CSS-eigenschappen, waardoor we de consistentie kunnen behouden en toch de flexibiliteit hebben om animaties aan te passen aan specifieke gebruiksscenario's, bijvoorbeeld als je een iets grotere 'puls'-animatie op één plek nodig hebt. Het bouwen van het eerste sleutelframetoken Een van de eerste laaghangende vruchten die we moeten aanpakken is de ‘fade-in’-animatie. In een van mijn recente projecten vond ik meer dan een dozijn afzonderlijke fade-in-definities, en ja, ze animeerden allemaal eenvoudigweg de dekking van 0 naar 1. Laten we dus een nieuw stylesheet maken, het kf-tokens.css noemen, het in ons project importeren en onze keyframes met het juiste commentaar erin plaatsen. /* keyframes-tokens.css */

/* * Fade In - vervaag entree-animatie * Gebruik: animatie: kf-fade-in 0,3s gemak-uit; */ @keyframes kf-fade-in { van { dekking: 0; } naar { dekking: 1; } }

Deze enkele @keyframes-declaratie vervangt al die verspreide fade-in-animaties in onze codebase. Schoon, eenvoudig en wereldwijd toepasbaar. En nu we dit token hebben gedefinieerd, kunnen we het vanuit elk onderdeel tijdens ons project gebruiken: .modaal { animatie: kf-fade-in 0,3s gemak-out; }

.tooltip { animatie: kf-fade-in 0,2s gemak-in-uit; }

.melding { animatie: kf-fade-in 0,5s easy-out; }

Bekijk de Pen Keyframes Tokens - Demo 2 [gevorkt] door Amit Sheen. Opmerking: we gebruiken het voorvoegsel kf- in al onze @keyframes-namen. Dit voorvoegsel dient als naamruimte die naamgevingsconflicten met bestaande animaties in het project voorkomt en meteen duidelijk maakt dat deze keyframes afkomstig zijn uit ons keyframes-tokensbestand. Een dynamische dia maken De kf-fade-in keyframes werken prima omdat ze eenvoudig zijn en er weinig ruimte is om dingen te verpesten. In andere animaties moeten we echter veel dynamischer zijn, en hier kunnen we de enorme kracht van aangepaste CSS-eigenschappen benutten. Dit is waar keyframe-tokens echt schitteren in vergelijking met verspreide statische animaties. Laten we een veelvoorkomend scenario nemen: ‘slide-in’-animaties. Maar waar vandaan glijden? 100px van rechts? 50% van links? Moet het vanaf de bovenkant van het scherm worden ingevoerd? Of misschien van onderaf naar binnen drijven? Zoveel mogelijkheden, maar in plaats van afzonderlijke keyframes te creëren voor elke richting en elke variatie, kunnen we één flexibel token bouwen dat zich aanpast aan alle scenario's: /* * Slide In - directionele dia-animatie * Gebruik --kf-slide-from om de richting te bepalen * Standaard: schuift van links naar binnen (-100%) * Gebruik: * animatie: kf-slide-in 0,3s gemak-uit; * --kf-dia-van: -100px 0; // schuif van links * --kf-slide-from: 100px 0; // schuif van rechts * --kf-dia-van: 0 -50px; // schuif van boven */

@keyframes kf-slide-in { van { vertalen: var(--kf-slide-from, -100% 0); } naar { vertalen: 0 0; } }

Nu kunnen we dit enkele @keyframes-token voor elke schuifrichting gebruiken, eenvoudigweg door de aangepaste eigenschap --kf-slide-from te wijzigen: .zijbalk { animatie: kf-slide-in 0,3s gemak-uit; /* Gebruikt standaardwaarde: dia's van links */ }

.melding { animatie: kf-slide-in 0,4s gemak-uit; --kf-dia-van: 0 -50px; /* schuif van boven */ }

.modaal { animatie: kf-fade-in 0,5s, kf-inschuifbare 0,5s kubieke bezier (0,34, 1,56, 0,64, 1); --kf-dia-van: 50px 50px; /* schuif van rechtsonder */ }

Deze aanpak geeft ons een ongelooflijke flexibiliteit terwijl de consistentie behouden blijft. Eén keyframe-declaratie, oneindige mogelijkheden. Bekijk de Pen Keyframes Tokens - Demo 3 [gevorkt] door Amit Sheen. En als we onze animaties nog flexibeler willen maken, en ook ‘slide-out’-effecten mogelijk willen maken, kunnen wevoeg eenvoudigweg een aangepaste eigenschap --kf-slide-to toe, vergelijkbaar met wat we in de volgende sectie zullen zien. Bidirectionele zoom-keyframes Een andere veel voorkomende animatie die in projecten wordt gedupliceerd, zijn 'zoom'-effecten. Of het nu gaat om een ​​subtiele opschaling voor toastberichten, een dramatische inzooming voor modaliteiten, of een zacht verkleiningseffect voor koppen, zoomanimaties zijn overal. In plaats van afzonderlijke hoofdframes te maken voor elke schaalwaarde, gaan we één flexibele set kf-zoom-hoofdframes bouwen:

/* * Zoom - schaalanimatie * Gebruik --kf-zoom-from en --kf-zoom-to om de schaalwaarden te beheren * Standaard: zoomt van 80% tot 100% (0,8 tot 1) * Gebruik: * animatie: kf-zoom 0,2s-ease-out; * --kf-zoom-vanaf: 0,5; --kf-zoom-naar: 1; // zoom van 50% naar 100% * --kf-zoom-van: 1; --kf-zoom-naar: 0; // zoom van 100% naar 0% * --kf-zoom-van: 1; --kf-zoom-naar: 1.1; // zoomen van 100% naar 110% */

@keyframes kf-zoom { van { schaal: var(--kf-zoom-van, 0,8); } naar { schaal: var(--kf-zoom-naar, 1); } }

Met één definitie kunnen we elke zoomvariatie bereiken die we nodig hebben: .toast { animatie: kf-inschuif 0,2s, kf-zoom 0,4s gemak-uit; --kf-schuif-van: 0 100%; /* schuif van boven */ /* Gebruikt standaardzoom: schaalt van 80% tot 100% */ }

.modaal { animatie: kf-zoom 0,3s kubieke bezier (0,34, 1,56, 0,64, 1); --kf-zoom-vanaf: 0; /* dramatische zoom van 0% tot 100% */ }

.kop { animatie: kf-fade-in 2s, kf-zoom 2s gemak-in; --kf-zoom-vanaf: 1,2; --kf-zoom-naar: 0,8; /* voorzichtig terugschalen */ }

De standaardwaarde van 0,8 (80%) werkt perfect voor de meeste UI-elementen, zoals toastberichten en kaarten, terwijl het toch gemakkelijk aan te passen is voor speciale gevallen. Bekijk de Pen Keyframes Tokens - Demo 4 [gevorkt] door Amit Sheen. Je hebt misschien iets interessants opgemerkt in de recente voorbeelden: we hebben animaties gecombineerd. Een van de belangrijkste voordelen van het werken met @keyframes-tokens is dat ze zijn ontworpen om naadloos met elkaar te integreren. Deze vloeiende compositie is opzettelijk en niet toevallig. We zullen de animatiecompositie later in meer detail bespreken, inclusief waar ze problematisch kunnen worden, maar de meeste combinaties zijn eenvoudig en gemakkelijk te implementeren. Opmerking: tijdens het schrijven van dit artikel, en misschien wel dankzij het schrijven ervan, merkte ik dat ik het hele idee van entree-animaties heroverwoog. Hebben we deze, met alle recente ontwikkelingen op het gebied van CSS, überhaupt nog nodig? Gelukkig heeft Adam Argyle dezelfde vragen onderzocht en deze op briljante wijze verwoord in zijn blog. Dit is niet in tegenspraak met wat hier geschreven staat, maar het biedt wel een aanpak die het overwegen waard is, vooral als uw projecten sterk afhankelijk zijn van entree-animaties. Continue animaties Terwijl entree-animaties, zoals ‘fade’, ‘slide’ en ‘zoom’ één keer plaatsvinden en dan stoppen, lopen continue animaties voor onbepaalde tijd door om de aandacht te trekken of lopende activiteit aan te geven. De twee meest voorkomende continue animaties die ik tegenkom zijn ‘spin’ (voor laadindicatoren) en ‘pulse’ (voor het benadrukken van belangrijke elementen). Deze animaties bieden unieke uitdagingen als het gaat om het maken van keyframes-tokens. In tegenstelling tot entreeanimaties die doorgaans van de ene toestand naar de andere gaan, moeten continue animaties in hoge mate aanpasbaar zijn in hun gedragspatronen. De Spindokter Elk project lijkt meerdere spin-animaties te gebruiken. Sommige draaien met de klok mee, andere tegen de klok in. Sommigen doen een enkele rotatie van 360 graden, anderen doen meerdere bochten voor een sneller effect. Laten we, in plaats van voor elke variatie afzonderlijke keyframes te maken, één flexibele draai maken die alle scenario's aankan:

/* * Spin - rotatie-animatie * Gebruik --kf-spin-from en --kf-spin-to om het rotatiebereik te regelen * Gebruik --kf-spin-turns om de rotatiehoeveelheid te regelen * Standaard: roteert van 0 graden tot 360 graden (1 volledige rotatie) * Gebruik: * animatie: kf-spin 1s lineair oneindig; * --kf-spin-turns: 2; // 2 volledige rotaties * --kf-spin-van: 0deg; --kf-spin-to: 180 graden; // halve rotatie * --kf-spin-van: 0deg; --kf-spin-to: -360 graden; // tegen de klok in */

@keyframes kf-spin { van { roteren: var(--kf-spin-from, 0deg); } naar { roteren: calc(var(--kf-spin-van, 0 graden) + var(--kf-spin-naar, 360 graden) * var(--kf-spin-turns, 1)); } }

Nu kunnen we elke gewenste spinvariatie creëren:

.laadspinner { animatie: kf-spin 1s lineair oneindig; /* Gebruikt standaard: roteert van 0 graden tot 360 graden */ }

.snellader { animatie: kf-spin 1.2s gemak-in-uit oneindig alternatief; --kf-spin-turns: 3; /* 3 volledige rotaties voor elke richting per cyclus*/ }

.stapte-achteruit { animatie: kf-spin 1,5s stappen(8) oneindig; --kf-spin-to: -360 graden; /* tegen de klok in */ }

.subtiel wiebelen { animatie: kf-spin 2s gemak-in-uit oneindig alternatief; --kf-spin-vanaf: -16 graden; --kf-spin-naar: 32 graden; /* wiebelen 36 graden: tussen -18 graden en +18 graden */ }

Bekijk de Pen Keyframes Tokens - Demo 5 [gevorkt] door Amit Sheen. Het mooie van deze aanpak is dat dezelfde keyframes werken voor het laden van spinners, roterende pictogrammen, wiebeleffecten en zelfs complexe animaties met meerdere beurten. De polsparadox Pulsanimaties zijn lastiger omdat ze verschillende eigenschappen kunnen 'pulseren'. Sommige pulseren de schaal, andere pulseren de dekking en sommige pulseren kleureigenschappen zoals helderheid of verzadiging. In plaats van voor elke eigenschap afzonderlijke hoofdframes te maken, kunnen we hoofdframes maken die met elke CSS-eigenschap werken. Hier is een voorbeeld van een pulshoofdframe met schaal- en dekkingsopties:

/* * Pulse - pulserende animatie * Gebruik --kf-pulse-scale-from en --kf-pulse-scale-to om het schaalbereik te regelen * Gebruik --kf-pulse-opacity-from en --kf-pulse-opacity-to om het dekkingsbereik te regelen * Standaard: geen puls (alle waarden 1) * Gebruik: * animatie: kf-pulse 2s gemak-in-uit oneindig alternatief; * --kf-pulsschaal-vanaf: 0,95; --kf-pulsschaal-tot: 1,05; // schaalpuls * --kf-puls-opaciteit-van: 0,7; --kf-puls-opaciteit-naar: 1; // dekkingspuls */

@keyframes kf-pulse { van { schaal: var(--kf-puls-schaal-van, 1); dekking: var(--kf-pulse-opaciteit-van, 1); } naar { schaal: var(--kf-puls-schaal-naar, 1); dekking: var(--kf-pulse-opaciteit-to, 1); } }

Hierdoor ontstaat een flexibele puls die meerdere eigenschappen kan animeren: .call-to-action { animatie: kf-puls 0,6s oneindig afwisselend; --kf-pulsopaciteit-van: 0,5; /* dekkingspuls */ }

.meldingspunt { animatie: kf-puls 0,6s gemak-in-uit oneindig alternatief; --kf-pulsschaal-vanaf: 0,9; --kf-pulsschaal-tot: 1,1; /* schaalpuls */ }

.text-highlight { animatie: kf-pulse 1,5s gemak-out oneindig; --kf-pulsschaal-van: 0,8; --kf-pulsopaciteit-van: 0,2; /* schaal en dekkingspuls */ }

Bekijk de Pen Keyframes Tokens - Demo 6 [gevorkt] door Amit Sheen. Dit enkele kf-pulse-keyframe kan alles aan, van subtiele aandachtstrekkers tot dramatische highlights, en is tegelijkertijd eenvoudig aan te passen. Geavanceerde versoepeling Een van de geweldige dingen van het gebruik van keyframes-tokens is hoe gemakkelijk het is om onze animatiebibliotheek uit te breiden en effecten te bieden die de meeste ontwikkelaars niet vanaf het begin zouden willen schrijven, zoals elastisch of stuiterend. Hier is een voorbeeld van een eenvoudig “bounce” keyframes-token dat een --kf-bounce-from aangepaste eigenschap gebruikt om de spronghoogte te regelen. /* * Stuiteren - stuiterende entree-animatie * Gebruik --kf-bounce-from om de spronghoogte te regelen * Standaard: springt van 100vh (buiten scherm) * Gebruik: * animatie: kf-bounce 3s-gemak; * --kf-bounce-van: 200px; // spring vanaf een hoogte van 200px */

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

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

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

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

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

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

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

22%, 45%, 64%, 79%, 90%, 97%, 100% { vertalen: 0 0; animatie-timing-functie: gemak-out; } }

Animaties zoals ‘elastisch’ zijn wat lastiger vanwege de berekeningen binnen de keyframes. We moeten --kf-elastic-from-X en --kf-elastic-from-Y afzonderlijk definiëren (beide zijn optioneel), en samen laten ze ons een elastische ingang creëren vanaf elk punt op het scherm.

/* * Elastic In - elastische entree-animatie * Gebruik --kf-elastic-from-X en --kf-elastic-from-Y om de startpositie te bepalen * Standaard: komt binnen vanuit het midden bovenaan (0, -100vh) * Gebruik: * animatie: kf-elastisch-in 2s gemak-in-uit beide; * --kf-elastisch-van-X: -50px; * --kf-elastisch-van-Y: -200px; // invoeren van (-50px, -200px) */

@keyframes kf-elastisch-in { 0% { vertalen: calc(var(--kf-elastisch-van-X, -50vw) * 1) calc(var(--kf-elastisch-van-Y, 0px) * 1); }

16% { vertalen: calc(var(--kf-elastisch-van-X, -50vw) * -0,3227) calc(var(--kf-elastisch-van-Y, 0px) * -0,3227); }

28% { vertalen: calc(var(--kf-elastisch-van-X, -50vw) * 0,1312)calc(var(--kf-elastisch-van-Y, 0px) * 0,1312); }

44% { vertalen: calc(var(--kf-elastisch-van-X, -50vw) * -0,0463) calc(var(--kf-elastisch-van-Y, 0px) * -0,0463); }

59% { vertalen: calc(var(--kf-elastisch-van-X, -50vw) * 0,0164) calc(var(--kf-elastisch-van-Y, 0px) * 0,0164); }

73% { vertalen: calc(var(--kf-elastisch-van-X, -50vw) * -0,0058) calc(var(--kf-elastisch-van-Y, 0px) * -0,0058); }

88% { vertalen: calc(var(--kf-elastisch-van-X, -50vw) * 0,0020) calc(var(--kf-elastisch-van-Y, 0px) * 0,0020); }

100% { vertalen: 0 0; } }

Deze aanpak maakt het gemakkelijk om geavanceerde keyframes in ons hele project opnieuw te gebruiken en aan te passen, gewoon door één enkele aangepaste eigenschap te wijzigen.

.bounce-en-zoom { animatie: kf-bounce 3s gemak-in, kf-zoom 3s lineair; --kf-zoom-vanaf: 0; }

.stuiteren en glijden { animatie-compositie: toevoegen; /* Beide animaties gebruiken vertalen */ animatie: kf-bounce 3s gemak-in, kf-inschuifbaar 3s gemak-uit; --kf-dia-van: -200px; }

.elastisch-in { animatie: kf-elastisch-in 2s gemak-in-uit beide; }

Bekijk de Pen Keyframes Tokens - Demo 7 [gevorkt] door Amit Sheen. Tot nu toe hebben we gezien hoe we keyframes op een slimme en efficiënte manier kunnen consolideren. Natuurlijk wilt u misschien dingen aanpassen om beter aan de behoeften van uw project te voldoen, maar we hebben voorbeelden besproken van verschillende veelvoorkomende animaties en alledaagse gebruiksscenario's. En nu deze keyframes-tokens aanwezig zijn, beschikken we nu over krachtige bouwstenen voor het creëren van consistente, onderhoudbare animaties voor het hele project. Geen dubbele keyframes meer, geen globale scope-conflicten meer. Gewoon een schone, handige manier om aan al onze animatiebehoeften te voldoen. Maar de echte vraag is: hoe stellen we deze bouwstenen samen? Alles samenvoegen We hebben gezien dat het combineren van basissleutelframetokens eenvoudig is. We hebben niets speciaals nodig dan de eerste animatie definiëren, de tweede definiëren, de variabelen naar behoefte instellen, en dat is alles. /* Infaden + inschuiven */ .toast { animatie: kf-fade-in 0,4s, kf-inschuifbare 0,4s kubieke bezier (0,34, 1,56, 0,64, 1); --kf-dia-van: 0 40px; }

/* Inzoomen + vervagen */ .modaal { animatie: kf-fade-in 0,3s, kf-zoom 0,3s kubieke bezier (0,34, 1,56, 0,64, 1); --kf-zoom-vanaf: 0,7; --kf-zoom-naar: 1; }

/* Inschuiven + puls */ .melding { animatie: kf-inschuifbaar 0,5s, kf-puls 1,2s gemak-in-uit oneindig afwisselend; --kf-dia-van: -100px 0; --kf-pulsschaal-vanaf: 0,95; --kf-pulsschaal-tot: 1,05; }

Deze combinaties werken prachtig omdat elke animatie zich op een andere eigenschap richt: dekking, transformatie (vertalen/schalen), enz. Maar soms zijn er conflicten en moeten we weten waarom en hoe we daarmee moeten omgaan. Wanneer twee animaties dezelfde eigenschap proberen te animeren (bijvoorbeeld beide animeren de schaal of beide animeren de dekking) zal het resultaat niet zijn wat u verwacht. Standaard wordt slechts één van de animaties daadwerkelijk op die eigenschap toegepast; dit is de laatste in de animatielijst. Dit is een beperking van de manier waarop CSS meerdere animaties op dezelfde eigenschap verwerkt. Dit zal bijvoorbeeld niet werken zoals bedoeld, omdat alleen de kf-pulse-animatie van toepassing zal zijn. .slechte combinatie { animatie: kf-zoom 0,5s vooruit, kf-puls 1,2s oneindig afwisselend; --kf-zoom-vanaf: 0,5; --kf-zoom-naar: 1,2; --kf-pulsschaal-van: 0,8; --kf-pulsschaal-tot: 1,1; }

Animatie toevoeging De eenvoudigste en meest directe manier om meerdere animaties te verwerken die dezelfde eigenschap beïnvloeden, is door de eigenschap animatiecompositie te gebruiken. In het laatste voorbeeld hierboven vervangt de kf-pulsanimatie de kf-zoomanimatie, dus we zullen de initiële zoom niet zien en zullen niet de verwachte schaal van 1,2 krijgen. Door de animatiecompositie in te stellen die moet worden toegevoegd, vertellen we de browser dat hij beide animaties moet combineren. Dit geeft ons het resultaat dat we willen. .component-twee { animatie-compositie: toevoegen; }

Bekijk de Pen Keyframes Tokens - Demo 8 [gevorkt] door Amit Sheen. Deze aanpak werkt goed in de meeste gevallen waarin we effecten op hetzelfde terrein willen combineren. Het is ook handig als we animaties moeten combineren met statische eigenschapswaarden. Als we bijvoorbeeld een element hebben dat de eigenschap 'translate' gebruikt om het precies te positioneren waar we willen, en we willen het dan animeren met de kf-slide-in keyframes, krijgen we een vervelende zichtbare sprong zonder animatiecompositie. Bekijk de Pen Keyframes Tokens - Demo 9 [gevorkt] door Amit Sheen. Als de animatiecompositie is ingesteld om toe te voegen, wordt de animatie vloeiend gecombineerd met de bestaandetransformeren, zodat het element op zijn plaats blijft en beweegt zoals verwacht. Animatie wankelen Een andere manier om met meerdere animaties om te gaan, is door ze te ‘spreiden’, dat wil zeggen door de tweede animatie te starten iets nadat de eerste is afgelopen. Het is geen oplossing die voor elk geval werkt, maar het is handig als we een ingangsanimatie hebben gevolgd door een doorlopende animatie. /* fade-in + dekkingspuls */ .melding { animatie: kf-fade-in 2s gemak-uit, kf-puls 0,5s 2s gemak-in-uit oneindig afwisselend; --kf-pulsopaciteit-tot: 0,5; }

Bekijk de Pen Keyframes Tokens - Demo 10 [gevorkt] door Amit Sheen. Bestel zaken Een groot deel van de animaties waarmee we werken, maakt gebruik van de eigenschap transform. In de meeste gevallen is dit gewoon handiger. Het heeft ook een prestatievoordeel omdat transformatie-animaties GPU-versneld kunnen worden. Maar als we transformaties gebruiken, moeten we accepteren dat de volgorde waarin we onze transformaties uitvoeren er toe doet. Veel. In onze keyframes tot nu toe hebben we individuele transformaties gebruikt. Volgens de specificaties worden deze altijd in een vaste volgorde toegepast: eerst wordt het element vertaald, vervolgens geroteerd en vervolgens geschaald. Dit is logisch en is wat de meesten van ons verwachten. Als we echter de eigenschap transform gebruiken, is de volgorde waarin de functies worden geschreven de volgorde waarin ze worden toegepast. Als we in dit geval iets 100 pixels op de X-as verplaatsen en het vervolgens 45 graden draaien, is dat niet hetzelfde als het eerst 45 graden draaien en het dan 100 pixels verplaatsen. /* Roze vierkant: eerst vertalen en dan roteren */ .voorbeeld-één { transformeren: vertalenX(100px) roteren(45 graden); }

/* Groen vierkant: eerst roteren en dan vertalen */ .voorbeeld-twee { transformeren: roteren(45 graden) vertalenX(100px); }

Bekijk de Pen Keyframes Tokens - Demo 11 [gevorkt] door Amit Sheen. Maar volgens de transformatievolgorde vinden alle individuele transformaties (alles wat we voor de keyframes-tokens hebben gebruikt) plaats vóór de transformatiefuncties. Dat betekent dat alles wat u in de transform-eigenschap instelt, na de animaties zal gebeuren. Maar als u bijvoorbeeld vertalen samen met de kf-spin-hoofdframes instelt, zal het vertalen vóór de animatie plaatsvinden. Nog in de war?! Dit leidt tot situaties waarin statische waarden verschillende resultaten kunnen veroorzaken voor dezelfde animatie, zoals in het volgende geval:

/* Gemeenschappelijke animatie voor beide spinners */ .spinner { animatie: kf-spin 1s lineair oneindig; }

/* Roze spinner: vertalen vóór roteren (individuele transformatie) */ .spinner-roze { vertalen: 100% 50%; }

/* Groene spinner: roteren en vervolgens vertalen (functievolgorde) */ .spinner-groen { transformeren: vertalen(100%, 50%); }

Bekijk de Pen Keyframes Tokens - Demo 12 [gevorkt] door Amit Sheen. Je kunt zien dat de eerste spinner (roze) een vertaling krijgt die plaatsvindt vóór de rotatie van kf-spin, dus hij beweegt eerst naar zijn plaats en draait dan. De tweede spinner (groen) krijgt een vertaal()-functie die plaatsvindt na de individuele transformatie, dus het element draait eerst en beweegt dan ten opzichte van zijn huidige hoek, en we krijgen dat brede baaneffect. Nee, dit is geen bug. Het is slechts een van de dingen die we moeten weten over CSS en waar we rekening mee moeten houden als we met meerdere animaties of meerdere transformaties werken. Indien nodig kunt u ook een extra set kf-spin-alt-hoofdframes maken die elementen roteren met behulp van de functierotatie(). Verminderde beweging En hoewel we het hebben over alternatieve keyframes, kunnen we de optie ‘geen animatie’ niet negeren. Een van de grootste voordelen van het gebruik van keyframes-tokens is dat toegankelijkheid kan worden ingebakken, en dat is eigenlijk vrij eenvoudig om te doen. Door onze keyframes te ontwerpen met het oog op toegankelijkheid, kunnen we ervoor zorgen dat gebruikers die de voorkeur geven aan verminderde beweging een vloeiendere, minder afleidende ervaring krijgen, zonder extra werk of duplicatie van code. De exacte betekenis van “Reduced Motion” kan enigszins variëren van de ene animatie tot de andere en van project tot project, maar hier zijn een paar belangrijke punten om in gedachten te houden: Sleutelframes dempen Hoewel sommige animaties kunnen worden verzacht of vertraagd, zijn er andere die volledig zouden moeten verdwijnen als er om verminderde beweging wordt gevraagd. Pulsanimaties zijn een goed voorbeeld. Om er zeker van te zijn dat deze animaties niet in de modus voor verminderde beweging worden uitgevoerd, kunnen we ze eenvoudigweg in de juiste mediaquery plaatsen.

@media (geeft de voorkeur aan verminderde beweging: geen voorkeur) { @keyfrmaes kf-pulse { van { schaal: var(--kf-puls-schaal-van, 1); dekking: var(--kf-pulse-opaciteit-van, 1); } naar { schaal: var(--kf-puls-schaal-naar, 1); dekking:var(--kf-puls-opaciteit-naar, 1); } } }

Dit zorgt ervoor dat gebruikers die voorkeur hebben ingesteld op reduceren de animatie niet zien en een ervaring krijgen die aansluit bij hun voorkeur. Direct binnen Er zijn enkele keyframes die we niet zomaar kunnen verwijderen, zoals entree-animaties. De waarde moet veranderen, moet animeren; anders heeft het element niet de juiste waarden. Maar bij verminderde beweging zou deze overgang van de beginwaarde onmiddellijk moeten plaatsvinden. Om dit te bereiken definiëren we een extra set keyframes waarbij de waarde onmiddellijk naar de eindstatus springt. Dit worden onze standaard keyframes. Vervolgens voegen we de reguliere hoofdframes toe aan een mediaquery voor voorkeuren voor verminderde beweging ingesteld op geen voorkeur, net als in het vorige voorbeeld. /* kom meteen binnen voor minder beweging */ @keyframes kf-zoom { van, naar { schaal: var(--kf-zoom-naar, 1); } }

@media (geeft de voorkeur aan verminderde beweging: geen voorkeur) { /* Originele zoom-keyframes */ @keyframes kf-zoom { van { schaal: var(--kf-zoom-van, 0,8); } naar { schaal: var(--kf-zoom-naar, 1); } } }

Op deze manier zien gebruikers die de voorkeur geven aan verminderde beweging het element onmiddellijk in de uiteindelijke staat verschijnen, terwijl alle anderen de geanimeerde overgang krijgen. De zachte aanpak Er zijn gevallen waarin we wel wat beweging willen behouden, maar dan veel zachter en rustiger dan de originele animatie. Zo kunnen we bijvoorbeeld een bounce-ingang vervangen door een zachte fade-in.

@keyframes kf-bounce { /* Zachte fade-in voor minder beweging */ }

@media (geeft de voorkeur aan verminderde beweging: geen voorkeur) { @keyframes kf-bounce { /* Originele bounce-keyframes */ } }

Nu krijgen gebruikers met verminderde beweging nog steeds een gevoel van uiterlijk, maar zonder de intense beweging van een stuiterende of elastische animatie. Nu de bouwstenen aanwezig zijn, is de volgende vraag hoe u ze onderdeel kunt maken van de daadwerkelijke workflow. Het schrijven van flexibele keyframes is één ding, maar om ze betrouwbaar te maken voor een groot project zijn een aantal strategieën nodig die ik op de harde manier heb moeten leren. Implementatiestrategieën en beste praktijken Als we eenmaal een solide bibliotheek met keyframes-tokens hebben, is de echte uitdaging hoe we deze in het dagelijkse werk kunnen gebruiken.

De verleiding is groot om alle keyframes er in één keer in te stoppen en het probleem opgelost te verklaren, maar in de praktijk heb ik gemerkt dat de beste resultaten voortkomen uit een geleidelijke adoptie. Begin met de meest voorkomende animaties, zoals fade of slide. Dit zijn gemakkelijke overwinningen die onmiddellijke waarde aantonen zonder dat grote herschrijvingen nodig zijn. Naamgeving is een ander punt dat aandacht verdient. Een consistent voorvoegsel of naamruimte maakt duidelijk welke animaties tokens zijn en welke lokale eenmalige acties zijn. Het voorkomt ook onbedoelde botsingen en helpt nieuwe teamleden het gedeelde systeem in één oogopslag te herkennen. Documentatie is net zo belangrijk als de code zelf. Zelfs een korte opmerking boven elk sleutelframetoken kan later urenlang raden besparen. Een ontwikkelaar moet het tokensbestand kunnen openen, scannen op het gewenste effect en het gebruikspatroon rechtstreeks naar zijn component kunnen kopiëren. Flexibiliteit maakt deze aanpak de moeite waard. Door verstandige aangepaste eigenschappen bloot te leggen, geven we teams de ruimte om de animatie aan te passen zonder het systeem kapot te maken. Probeer het tegelijkertijd niet te ingewikkeld te maken. Zorg voor de knoppen die er toe doen en houd de rest eigenzinnig. Denk ten slotte aan de toegankelijkheid. Niet elke animatie heeft een alternatief met verminderde beweging nodig, maar veel animaties wel. Door deze aanpassingen vroegtijdig in te voeren, hoeven we ze later nooit meer aan te passen, en het getuigt van een zorgniveau dat onze gebruikers zullen opmerken, zelfs als ze er nooit over praten.

Mijn ervaring is dat het behandelen van keyframes-tokens als onderdeel van onze ontwerptokens-workflow ervoor zorgt dat ze blijven hangen. Als ze eenmaal op hun plaats zitten, voelen ze niet langer als speciale effecten en worden ze onderdeel van de ontwerptaal, een natuurlijke uitbreiding van hoe het product beweegt en reageert. Inpakken Animaties kunnen een van de leukste onderdelen zijn van het bouwen van interfaces, maar zonder structuur kunnen ze ook een van de grootste bronnen van frustratie worden. Door keyframes als tokens te behandelen, verander je iets dat doorgaans rommelig en moeilijk te beheren is in een duidelijk, voorspelbaar systeem. De echte waarde ligt niet alleen in het opslaan van een paar regels code. Het ligt in het vertrouwen dat wanneer u een fade, slide, zoom of spin gebruikt, u precies weet hoe deze zich in het hele project zal gedragen. Het zit in de flexibiliteit die voortkomt uit aangepaste eigenschappen zonder de chaos van eindeloze variaties. En het zit in de toegankelijkheid die in de basis is ingebouwd in plaats van toegevoegdeen bijzaak. Ik heb deze ideeën zien werken in verschillende teams en verschillende codebases, en het patroon is altijd hetzelfde. Zodra de tokens op hun plaats zitten, zijn keyframes niet langer een verspreide verzameling trucs, maar worden ze onderdeel van de ontwerptaal. Ze zorgen ervoor dat het product opzettelijker, consistenter en levendiger aanvoelt. Als je één ding uit dit artikel overneemt, laat het dit zijn: animaties verdienen dezelfde zorg en structuur die we al aan kleuren, typografie en spatiëring geven. Een kleine investering in keyframes-tokens loont elke keer dat uw interface beweegt.

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