Şunu hayal edin: Yeni bir projeye katılıyorsunuz, kod tabanına dalıyorsunuz ve ilk birkaç saat içinde sinir bozucu derecede tanıdık bir şey keşfediyorsunuz. Stil sayfalarına dağılmış olarak, aynı temel animasyonlar için birden fazla @keyframes tanımı bulacaksınız. Üç farklı solma efekti, iki veya üç slayt varyasyonu, bir avuç yakınlaştırma animasyonu ve en az iki farklı döndürme animasyonu, çünkü neden olmasın? @keyframes darbesi { {'den ölçek: 1; } {'e ölçek: 1.1; } }
@keyframes daha büyük darbe { %0, %20, %100 { ölçek: 1; } %10, %40 { ölçek: 1,2; } }
Bu senaryo tanıdık geliyorsa yalnız değilsiniz. Çeşitli projelerdeki deneyimime göre, sağlayabileceğim en tutarlı hızlı kazanımlardan biri ana kareleri birleştirmek ve standartlaştırmaktır. Bu o kadar güvenilir bir kalıp haline geldi ki artık herhangi bir yeni kod tabanındaki ilk görevlerimden biri olarak bu temizliği sabırsızlıkla bekliyorum. Kaosun Arkasındaki Mantık Bu fazlalık, düşündüğünüzde çok mantıklı geliyor. Günlük çalışmalarımızda hepimiz aynı temel animasyonları kullanırız: karartmalar, slaytlar, yakınlaştırmalar, döndürmeler ve diğer yaygın efektler. Bu animasyonlar oldukça basittir ve işin tamamlanması için hızlı bir @keyframes tanımı oluşturmak kolaydır. Merkezi bir animasyon sistemi olmadan geliştiriciler, benzer animasyonların kod tabanının başka bir yerinde zaten mevcut olduğunun farkında olmadan doğal olarak bu anahtar kareleri sıfırdan yazarlar. Ekipler genellikle uygulamanın farklı bölümlerinde paralel olarak çalıştığından, bu durum özellikle bileşen tabanlı mimarilerde çalışırken yaygındır (bugünlerde çoğumuz bunu yapıyoruz). Sonuç? Animasyon kaosu. Küçük Sorun Anahtar karelerin çoğaltılmasıyla ilgili en belirgin sorunlar, boşa harcanan geliştirme süresi ve gereksiz kod şişkinliğidir. Çoklu animasyon karesi tanımları, gereksinimler değiştiğinde güncellenecek birden fazla yer anlamına gelir. Solma animasyonunuzun zamanlamasını ayarlamanız mı gerekiyor? Kod tabanınızdaki her örneği bulmanız gerekecek. Hareket hızı işlevlerini standartlaştırmak mı istiyorsunuz? Tüm varyasyonları bulmada iyi şanslar. Bakım noktalarının bu şekilde çoğalması, basit animasyon güncellemelerini bile zaman alan bir görev haline getiriyor. Daha Büyük Sorun Bu anahtar karelerin kopyalanması, yüzeyin altında gizlenen çok daha sinsi bir sorun yaratır: küresel kapsam tuzağı. Bileşen tabanlı mimarilerle çalışırken bile CSS ana kareleri her zaman global kapsamda tanımlanır. Bu, tüm anahtar karelerin tüm bileşenlere uygulanacağı anlamına gelir. Her zaman. Evet, animasyonunuzun mutlaka bileşeninizde tanımladığınız ana kareleri kullanması gerekmez. Global kapsama yüklenen adla tamamen aynı olan son anahtar kareleri kullanır. Tüm ana kareleriniz aynı olduğu sürece bu küçük bir sorun gibi görünebilir. Ancak bir animasyonu belirli bir kullanım durumuna göre özelleştirmek istediğiniz anda başınız belaya girer veya daha kötüsü, bunlara neden olan siz olursunuz. Ya animasyonunuz, sizinkinden sonra başka bir bileşen yüklendiğinden, ana karelerinizin üzerine yazıldığından ya da bileşeniniz en son yüklendiğinden ve o ana karenin adını kullanarak diğer tüm bileşenlerin animasyon davranışını yanlışlıkla değiştirdiğinden dolayı çalışmayacaktır ve siz bunun farkına bile varmayabilirsiniz. İşte sorunu gösteren basit bir örnek: .bileşen-bir { /* bileşen stilleri */ animasyon: darbe 1'lerin giriş-çıkış kolaylığı sonsuz alternatif; }
/* bu @keyframes tanımı çalışmayacak */ @keyframes darbesi { {'den ölçek: 1; } {'e ölçek: 1.1; } }
/* kodun ilerleyen kısımlarında... */
.bileşen-iki { /* bileşen stilleri */ animasyon: darbe 1'lerin sonsuz giriş-çıkış kolaylığı; }
/* bu anahtar kareler her iki bileşene de uygulanacaktır */ @keyframes darbesi { %0, %20, %100 { ölçek: 1; } %10, %40 { ölçek: 1,2; } }
Her iki bileşen de aynı animasyon adını kullanır ancak ikinci @keyframes tanımı birincinin üzerine yazar. Artık hem birinci bileşen hem de ikinci bileşen, hangi bileşenin hangi anahtar kareleri tanımladığına bakılmaksızın ikinci anahtar kareleri kullanacaktır. Amit Sheen tarafından yazılan Pen Keyframes Tokens - Demo 1'e [çatallı] bakın. En kötü kısım mı? Bu genellikle yerel geliştirmede mükemmel çalışır, ancak yapım süreçleri stil sayfalarınızın yükleme sırasını değiştirdiğinde üretimde gizemli bir şekilde bozulur. Hangi bileşenlerin hangi sırayla yüklendiğine bağlı olarak farklı davranan animasyonlarla karşılaşırsınız. Çözüm: Birleştirilmiş Anahtar Kareler Bu kaosun cevabı şaşırtıcı derecede basit: paylaşılan bir stil sayfasında saklanan önceden tanımlanmış dinamik anahtar kareler. Her bileşenin kendi animasyonlarını tanımlamasına izin vermek yerine, iyi belgelenmiş, kullanımı kolay, merkezileştirilmiş anahtar kareler oluşturuyoruz.Kullanılabilir, bakımı yapılabilir ve projenizin özel ihtiyaçlarına göre uyarlanabilir. Bunu anahtar kare belirteçleri olarak düşünün. Tıpkı renkler ve aralıklar için belirteçler kullandığımız ve çoğumuz zaten süre ve hareket hızı işlevleri gibi animasyon özellikleri için belirteçler kullandığımız gibi, neden anahtar kareler için de belirteçler kullanmayalım? Bu yaklaşım, hem küçük sorunu (kod çoğaltma) hem de daha büyük sorunu (küresel kapsam çatışmaları) tek seferde çözerken, kullandığınız herhangi bir mevcut tasarım belirteci iş akışıyla doğal olarak bütünleşebilir. Fikir çok basit: tüm ortak animasyonlarımız için tek bir doğruluk kaynağı yaratmak. Bu paylaşılan stil sayfası, projemizin gerçekte kullandığı animasyon modellerini kapsayan özenle hazırlanmış anahtar kareler içerir. Artık kod tabanımızda bir yerde solma animasyonunun mevcut olup olmadığını tahmin etmenize gerek yok. Artık yanlışlıkla diğer bileşenlerdeki animasyonların üzerine yazmaya gerek yok. Ancak işin anahtarı şu: Bunlar yalnızca statik kopyala-yapıştır animasyonları değil. CSS özel özellikleri aracılığıyla dinamik ve özelleştirilebilir olacak şekilde tasarlandıkları için, tutarlılığı korurken aynı zamanda animasyonları belirli kullanım durumlarına (örneğin, tek bir yerde biraz daha büyük bir "darbeli" animasyona ihtiyaç duymanız durumunda) uyarlama esnekliğine sahip olmamızı sağlar. İlk Keyframes Tokenını Oluşturmak Ele almamız gereken ilk alçak meyvelerden biri "kaybolma" animasyonudur. Son projelerimden birinde, bir düzineden fazla ayrı fade-in tanımı buldum ve evet, hepsi opaklığı 0'dan 1'e kadar basitçe canlandırdı. Öyleyse yeni bir stil sayfası oluşturalım, buna kf-tokens.css adını verelim, projemize aktaralım ve içine uygun yorumlarla birlikte ana karelerimizi yerleştirelim. /* anahtar kareler-tokens.css */
/* * Fade In - solmaya giriş animasyonu * Kullanım: animasyon: kf-fade-in 0,3 saniyelik yavaşlama; */ @keyframes kf-fade-in { {'den opaklık: 0; } {'e opaklık: 1; } }
Bu tek @keyframes bildirimi, kod tabanımızdaki tüm dağınık geçişli animasyonların yerini alır. Temiz, basit ve küresel olarak uygulanabilir. Artık bu belirteci tanımladığımıza göre, onu projemiz boyunca herhangi bir bileşenden kullanabiliriz: .modal { animasyon: kf-fade-in 0,3 saniyelik yavaşlama; }
.araç ipucu { animasyon: kf-fade-in 0,2 saniyelik giriş kolaylığı; }
.bildirim { animasyon: kf-fade-in 0,5 saniyelik yavaşlama; }
Amit Sheen'in yazdığı Pen Keyframes Tokens - Demo 2'ye [çatallı] bakın. Not: Tüm @keyframes adlarımızda kf- önekini kullanıyoruz. Bu önek, projedeki mevcut animasyonlarla adlandırma çakışmalarını önleyen bir ad alanı görevi görür ve bu anahtar karelerin, anahtar kare belirteçleri dosyamızdan geldiğinin hemen anlaşılmasını sağlar. Dinamik Slayt Oluşturma Kf-fade-in ana kareleri harika çalışıyor çünkü basit ve işleri karıştıracak çok az yer var. Ancak diğer animasyonlarda çok daha dinamik olmamız gerekiyor ve burada CSS özel özelliklerinin muazzam gücünden yararlanabiliriz. Anahtar kare belirteçlerinin dağınık statik animasyonlarla karşılaştırıldığında gerçekten parladığı yer burasıdır. Yaygın bir senaryoyu ele alalım: “içeriye kayan” animasyonlar. Ama nereden içeri gireceksin? Sağdan 100px? %50 soldan mı? Ekranın üst kısmından mı girmeli? Ya da belki alttan yüzer misiniz? Pek çok olasılık var, ancak her yön ve her varyasyon için ayrı anahtar kareler oluşturmak yerine, tüm senaryolara uyum sağlayan esnek bir token oluşturabiliriz: /* * İçeri Kaydır - yönlü slayt animasyonu * Yönü kontrol etmek için --kf-slide-from kullanın * Varsayılan: soldan içeri kayar (-%100) * Kullanımı: * animasyon: kf-slide-in 0,3 saniyelik yavaşlama; * --kf-slide-from: -100px 0; //soldan kaydır * --kf-slayt-from: 100px 0; //sağdan kaydır * --kf-slayt-from: 0 -50px; // üstten kaydır */
@keyframes kf-slide-in { {'den tercüme: var(--kf-slide-from, -100% 0); } {'e çevir: 0 0; } }
Artık bu tek @keyframes belirtecini --kf-slide-from özel özelliğini değiştirerek herhangi bir slayt yönü için kullanabiliriz: .kenar çubuğu { animasyon: kf-slide-in 0,3 saniyelik yavaşlama; /* Varsayılan değeri kullanır: soldan kaydırır */ }
.bildirim { animasyon: kf-slide-in 0,4 saniyelik yavaşlama; --kf-slayt-from: 0 -50px; /* üstten kaydır */ }
.modal { animasyon: kf-fade-in 0,5 saniye, kf-içeriye kaydırma 0,5s kübik-bezier(0,34, 1,56, 0,64, 1); --kf-slayt-from: 50px 50px; /* sağ alttan kaydırın */ }
Bu yaklaşım bize tutarlılığı korurken inanılmaz bir esneklik sağlıyor. Tek bir ana kare bildirimi, sonsuz olasılıklar. Amit Sheen'in yazdığı Pen Keyframes Tokens - Demo 3'e [çatallı] bakın. Animasyonlarımızı "dışarıya kaydırma" efektlerine de olanak tanıyacak şekilde daha esnek hale getirmek istersek bunu yapabiliriz.sonraki bölümde göreceğimize benzer şekilde --kf-slide-to özel özelliğini eklemeniz yeterlidir. Çift Yönlü Yakınlaştırma Ana Kareleri Projeler arasında kopyalanan bir diğer yaygın animasyon da "yakınlaştırma" efektleridir. İster tost mesajları için ince bir ölçek büyütme, modeller için çarpıcı bir yakınlaştırma, ister başlıklar için hafif bir ölçek küçültme efekti olsun, yakınlaştırma animasyonları her yerdedir. Her ölçek değeri için ayrı anahtar kareler oluşturmak yerine, esnek bir kf-zoom anahtar kareleri kümesi oluşturalım:
/* * Yakınlaştırma - ölçeklendirme animasyonu * Ölçek değerlerini kontrol etmek için --kf-zoom-from ve --kf-zoom-to kullanın * Varsayılan: %80'den %100'e (0,8'den 1'e) yakınlaştırır * Kullanımı: * animasyon: kf-zoom 0,2 saniyelik kolaylık; * --kf-zoom-from: 0,5; --kf-zoom-to: 1; // %50'den %100'e yakınlaştırma * --kf-zoom-from: 1; --kf-zoom-to: 0; // %100'den %0'a yakınlaştırma * --kf-zoom-from: 1; --kf-zoom-to: 1.1; // %100'den %110'a yakınlaştır */
@keyframes kf-zoom { {'den ölçek: var(--kf-zoom-from, 0,8); } {'e ölçek: var(--kf-zoom-to, 1); } }
Tek bir tanımla ihtiyacımız olan herhangi bir yakınlaştırma varyasyonunu elde edebiliriz: .tost { animasyon: kf-kayma 0,2 saniye, kf-zoom 0,4 saniyelik yavaşlama; --kf-slide-from: 0 100%; /* üstten kaydır */ /* Varsayılan yakınlaştırmayı kullanır: %80'den %100'e ölçeklenir */ }
.modal { animasyon: kf-zoom 0,3s kübik-bezier(0,34, 1,56, 0,64, 1); --kf-zoom-from: 0; /* %0'dan %100'e dramatik yakınlaştırma */ }
.başlık { animasyon: kf-fade-in 2'ler, kf-zoom 2'nin kolaylığı; --kf-zoom-from: 1.2; --kf-zoom-to: 0,8; /* ölçeği yavaşça küçült */ }
Varsayılan 0,8 (%80) değeri, mesaj mesajları ve kartlar gibi çoğu kullanıcı arayüzü öğesi için mükemmel şekilde çalışır ve özel durumlar için özelleştirilmesi yine de kolaydır. Amit Sheen'in yazdığı Pen Keyframes Tokens - Demo 4'e [çatallı] bakın. Son örneklerde ilginç bir şey fark etmiş olabilirsiniz: Animasyonları birleştiriyoruz. @keyframes tokenlarıyla çalışmanın en önemli avantajlarından biri, birbirleriyle sorunsuz bir şekilde entegre olacak şekilde tasarlanmış olmalarıdır. Bu pürüzsüz kompozisyon kasıtlıdır, tesadüfi değildir. Animasyon kompozisyonunu daha sonra, sorunlu olabileceği yerler de dahil olmak üzere daha ayrıntılı olarak ele alacağız, ancak çoğu kombinasyon basit ve uygulanması kolaydır. Not: Bu makaleyi yazarken ve belki de yazarken kendimi giriş animasyonları fikrini yeniden düşünürken buldum. CSS'deki son gelişmelere rağmen bunlara hâlâ ihtiyacımız var mı? Şans eseri Adam Argyle aynı soruları araştırdı ve bunları blogunda harika bir şekilde ifade etti. Bu, burada yazılanlarla çelişmiyor ancak özellikle projeleriniz ağırlıklı olarak giriş animasyonlarına dayanıyorsa dikkate alınmaya değer bir yaklaşım sunuyor. Sürekli Animasyonlar “Kaybolma”, “kayma” ve “yakınlaştırma” gibi giriş animasyonları bir kez gerçekleşip sonra dururken, sürekli animasyonlar dikkat çekmek veya devam eden etkinliği belirtmek için süresiz olarak döngü yapar. Karşılaştığım en yaygın iki sürekli animasyon, "döndürme" (yükleme göstergeleri için) ve "darbe" (önemli öğeleri vurgulamak için)'dir. Bu animasyonlar, anahtar kare belirteçleri oluşturma konusunda benzersiz zorluklar sunar. Genellikle bir durumdan diğerine giden giriş animasyonlarının aksine, sürekli animasyonların davranış kalıplarının son derece özelleştirilebilir olması gerekir. Döndürme Doktoru Her proje birden fazla döndürme animasyonu kullanıyor gibi görünüyor. Bazıları saat yönünde, bazıları ise saat yönünün tersine döner. Bazıları tek bir 360 derecelik dönüş yaparken, diğerleri daha hızlı bir etki için birden fazla dönüş yapar. Her varyasyon için ayrı anahtar kareler oluşturmak yerine, tüm senaryoları ele alan esnek bir dönüş oluşturalım:
/* * Döndürme - döndürme animasyonu * Dönüş aralığını kontrol etmek için --kf-spin-from ve --kf-spin-to kullanın * Dönüş miktarını kontrol etmek için --kf-spin-turns kullanın * Varsayılan: 0 dereceden 360 dereceye kadar döner (1 tam dönüş) * Kullanımı: * animasyon: kf-spin 1s doğrusal sonsuz; * --kf-döndürme-dönüşleri: 2; // 2 tam dönüş * --kf-spin-from: 0 derece; --kf-döndürme: 180 derece; // yarım dönüş * --kf-spin-from: 0 derece; --kf-döndürme: -360 derece; // saat yönünün tersine */
@keyframes kf-spin { {'den döndürme: var(--kf-spin-from, 0deg); } {'e döndürme: calc(var(--kf-döndürme-başlangıç, 0 derece) + var(--kf-döndürme, 360 derece) * var(--kf-döndürme-döndürme, 1)); } }
Artık istediğimiz herhangi bir döndürme varyasyonunu yaratabiliriz:
.loading-döndürücü { animasyon: kf-spin 1s doğrusal sonsuz; /* Varsayılanı kullanır: 0 dereceden 360 dereceye döner */ }
.hızlı yükleyici { animasyon: kf-spin 1,2 saniyelik giriş-çıkış sonsuz alternatif; --kf-spin-dönüşleri: 3; /* Döngü başına her yön için 3 tam dönüş*/ }
.steped-reverse { animasyon: kf-spin 1,5 saniyelik adımlar(8) sonsuz; --kf-döndürme: -360 derece; /* saat yönünün tersine */ }
.ince-kıpırdat { animasyon: kf-spin 2s kolay giriş-çıkış sonsuz alternatif; --kf-spin-from: -16deg; --kf-döndürme: 32 derece; /* 36 derece kıpırdat: -18 derece ile +18 derece arasında */ }
Amit Sheen tarafından yazılan Pen Keyframes Tokens - Demo 5'e [çatallı] bakın. Bu yaklaşımın güzelliği, aynı anahtar karelerin dönen çarkları yüklemek, simgeleri döndürmek, kıpırdatma efektleri ve hatta karmaşık çok dönüşlü animasyonlar için de çalışmasıdır. Nabız Paradoksu Darbeli animasyonlar daha yanıltıcıdır çünkü farklı özellikleri "darbeli" hale getirebilirler. Bazıları ölçeği titreştirirken, diğerleri opaklığı titreştirir ve bazıları parlaklık veya doygunluk gibi renk özelliklerini titreştirir. Her özellik için ayrı anahtar kareler oluşturmak yerine, herhangi bir CSS özelliğiyle çalışan anahtar kareler oluşturabiliriz. Ölçek ve opaklık seçeneklerine sahip bir darbe ana karesinin bir örneğini burada bulabilirsiniz:
/* * Darbe - darbeli animasyon * Ölçek aralığını kontrol etmek için --kf-pulse-scale-from ve --kf-pulse-scale-to kullanın * Opaklık aralığını kontrol etmek için --kf-pulse-opacity-from ve --kf-pulse-opacity-to kullanın * Varsayılan: darbe yok (tüm değerler 1) * Kullanımı: * animasyon: kf-pulse 2'lerin kolay giriş-çıkış sonsuz alternatifi; * --kf-pulse-scale-from: 0,95; --kf-darbe ölçeği-to: 1,05; // ölçek darbesi * --kf-pulse-opacity-from: 0,7; --kf-darbe-opaklığı-to: 1; // opaklık darbesi */
@keyframes kf darbesi { {'den ölçek: var(--kf-pulse-scale-from, 1); opaklık: var(--kf-pulse-opacity-from, 1); } {'e ölçek: var(--kf-darbe-ölçek-to, 1); opaklık: var(--kf-darbe-opaklık-to, 1); } }
Bu, birden fazla özelliği canlandırabilecek esnek bir darbe oluşturur: .harekete geçirici mesaj { animasyon: kf-pulse 0,6s sonsuz alternatif; --kf-pulse-opacity-from: 0,5; /* opaklık darbesi */ }
.bildirim-nokta { animasyon: kf-pulse 0,6 saniyelik giriş-çıkış sonsuz alternatif; --kf-pulse-scale-from: 0,9; --kf-darbe ölçeği-to: 1.1; /* ölçek darbesi */ }
.text-highlight { animasyon: kf-pulse 1,5 saniyelik sonsuz hareket hızı; --kf-pulse-scale-from: 0,8; --kf-pulse-opacity-from: 0,2; /* ölçek ve opaklık darbesi */ }
Amit Sheen tarafından yazılan Pen Keyframes Tokens - Demo 6'ya [çatallı] bakın. Bu tek kf-pulse ana karesi, özelleştirilmesi kolay olmakla birlikte, dikkat çekmeyen dikkat çekici noktalardan dramatik vurgulara kadar her şeyin üstesinden gelebilir. Gelişmiş Yumuşak Geçiş Anahtar kare belirteçlerini kullanmanın en güzel yanlarından biri, animasyon kitaplığımızı genişletmenin ve çoğu geliştiricinin elastik veya sıçrama gibi sıfırdan yazmaya zahmet etmeyeceği efektleri sağlamanın ne kadar kolay olmasıdır. Atlama yüksekliğini kontrol etmek için --kf-bounce-from özel özelliğini kullanan basit bir "sıçrama" anahtar kare belirtecinin bir örneğini burada bulabilirsiniz. /* * Sıçrama - sıçrayan giriş animasyonu * Atlama yüksekliğini kontrol etmek için --kf-bounce-from kullanın * Varsayılan: 100vh'den atlar (ekran dışı) * Kullanımı: * animasyon: kf-bounce 3'lü kolaylık; * --kf-bounce-from: 200px; // 200 piksel yükseklikten atla */
@keyframes kf-bounce { %0 { tercüme et: 0 calc(var(--kf-bounce-from, 100vh) * -1); }
%34 { tercüme: 0 calc(var(--kf-bounce-from, 100vh) * -0,4); }
%55 { tercüme: 0 calc(var(--kf-bounce-from, 100vh) * -0,2); }
%72 { tercüme: 0 calc(var(--kf-bounce-from, 100vh) * -0,1); }
%85 { tercüme: 0 calc(var(--kf-bounce-from, 100vh) * -0,05); }
%94 { tercüme: 0 calc(var(--kf-bounce-from, 100vh) * -0,025); }
%99 { tercüme: 0 calc(var(--kf-bounce-from, 100vh) * -0,0125); }
%22, %45, %64, %79, %90, %97, %100 { çevir: 0 0; animasyon zamanlama işlevi: kolaylaştırma; } }
"Elastik" gibi animasyonlar, ana karelerin içindeki hesaplamalar nedeniyle biraz daha yanıltıcıdır. --kf-elastic-from-X ve --kf-elastic-from-Y'yi ayrı ayrı tanımlamamız gerekiyor (her ikisi de isteğe bağlı) ve birlikte ekranın herhangi bir noktasından elastik bir giriş oluşturmamıza izin veriyorlar.
/* * Elastik Giriş - elastik giriş animasyonu * Başlangıç konumunu kontrol etmek için --kf-elastic-from-X ve --kf-elastic-from-Y'yi kullanın * Varsayılan: üst merkezden girer (0, -100vh) * Kullanımı: * animasyon: kf-elastik giriş 2'li çıkış kolaylığı; * --kf-elastic-from-X: -50px; * --kf-elastic-from-Y: -200px; // (-50px, -200px)'den girin */
@keyframes kf-elastic-in { %0 { tercüme: calc(var(--kf-elastic-from-X, -50vw) * 1) calc(var(--kf-elastic-from-Y, 0px) * 1); }
%16 { tercüme: calc(var(--kf-elastic-from-X, -50vw) * -0.3227) calc(var(--kf-elastic-from-Y, 0px) * -0.3227); }
%28 { tercüme et: calc(var(--kf-elastic-from-X, -50vw) * 0.1312)calc(var(--kf-elastic-from-Y, 0px) * 0.1312); }
%44 { tercüme: calc(var(--kf-elastic-from-X, -50vw) * -0.0463) calc(var(--kf-elastic-from-Y, 0px) * -0.0463); }
%59 { tercüme: calc(var(--kf-elastic-from-X, -50vw) * 0,0164) calc(var(--kf-elastic-from-Y, 0px) * 0,0164); }
%73 { tercüme: calc(var(--kf-elastic-from-X, -50vw) * -0,0058) calc(var(--kf-elastic-from-Y, 0px) * -0,0058); }
%88 { tercüme: calc(var(--kf-elastic-from-X, -50vw) * 0,0020) calc(var(--kf-elastic-from-Y, 0px) * 0,0020); }
%100 { çevir: 0 0; } }
Bu yaklaşım, yalnızca tek bir özel özelliği değiştirerek projemiz genelinde gelişmiş anahtar karelerin yeniden kullanılmasını ve özelleştirilmesini kolaylaştırır.
.sıçrama ve yakınlaştırma { animasyon: kf-bounce 3s kolaylığı, kf-zoom 3s doğrusal; --kf-zoom-from: 0; }
.zıpla ve kay { animasyon kompozisyonu: ekle; /* Her iki animasyon da çeviriyi kullanıyor */ animasyon: kf-bounce 3s kolaylığı, kf-içeriye kaydırmalı 3'lü çıkış kolaylığı; --kf-slayt-from: -200px; }
.elastik giriş { animasyon: kf-elastic-in 2'ler her ikisi de kolay giriş-çıkış; }
Amit Sheen'in yazdığı Pen Keyframes Tokens - Demo 7'ye [çatallı] bakın. Bu noktaya kadar ana kareleri akıllı ve verimli bir şekilde nasıl birleştirebileceğimizi gördük. Elbette projenizin ihtiyaçlarına daha iyi uyacak şekilde bazı şeylerde değişiklik yapmak isteyebilirsiniz, ancak birkaç yaygın animasyon ve günlük kullanım örneğine değindik. Ve bu anahtar kare belirteçlerinin mevcut olmasıyla, artık tüm proje boyunca tutarlı, sürdürülebilir animasyonlar oluşturmak için güçlü yapı taşlarına sahibiz. Artık yinelenen anahtar kareler yok, artık küresel kapsam çakışmaları yok. Tüm animasyon ihtiyaçlarımızı karşılamanın temiz ve kullanışlı bir yolu. Ancak asıl soru şu: Bu yapı taşlarını nasıl bir araya getireceğiz? Hepsini Bir Araya Getirmek Temel anahtar kare belirteçlerini birleştirmenin basit olduğunu gördük. İlk animasyonu tanımlamak, ikincisini tanımlamak, değişkenleri gerektiği gibi ayarlamak dışında özel bir şeye ihtiyacımız yok, hepsi bu. /* Yavaşça belir + kaydır */ .tost { animasyon: kf-fade-in 0,4 saniye, kf-içeriye kaydırma 0,4s kübik-bezier(0,34, 1,56, 0,64, 1); --kf-slayt-from: 0 40px; }
/* Yakınlaştır + karart */ .modal { animasyon: kf-fade-in 0,3 saniye, kf-yakınlaştırma 0,3s kübik-bezier(0,34, 1,56, 0,64, 1); --kf-zoom-from: 0,7; --kf-zoom-to: 1; }
/* İçeri kaydır + darbe */ .bildirim { animasyon: kf-kayma 0,5 saniye, kf-pulse 1,2 sn kolay giriş-çıkış sonsuz alternatif; --kf-slayt-from: -100px 0; --kf-pulse-scale-from: 0,95; --kf-darbe ölçeği-to: 1,05; }
Bu kombinasyonlar harika çalışır çünkü her animasyon farklı bir özelliği hedefler: opaklık, dönüşüm (çevirme/ölçekleme), vb. Ancak bazen çatışmalar olabilir ve bunların nedenini ve bunlarla nasıl başa çıkacağımızı bilmemiz gerekir. İki animasyon aynı özelliği canlandırmaya çalıştığında (örneğin, her ikisi de animasyon ölçeği veya her ikisi de animasyon opaklığı), sonuç beklediğiniz gibi olmayacaktır. Varsayılan olarak, animasyon listesindeki sonuncu olan bu özelliğe aslında animasyonlardan yalnızca biri uygulanır. Bu, CSS'nin aynı özellikteki birden fazla animasyonu nasıl işlediğine ilişkin bir sınırlamadır. Örneğin, yalnızca kf-pulse animasyonu uygulanacağından bu amaçlandığı gibi çalışmayacaktır. .kötü-kombinasyon { animasyon: kf-zoom 0,5 saniye ileri, kf-pulse 1,2s sonsuz alternatif; --kf-zoom-from: 0,5; --kf-zoom-to: 1,2; --kf-pulse-scale-from: 0,8; --kf-darbe ölçeği-to: 1.1; }
Animasyon Ekleme Aynı özelliği etkileyen birden fazla animasyonu işlemenin en basit ve en doğrudan yolu, animasyon-kompozisyon özelliğini kullanmaktır. Yukarıdaki son örnekte, kf-pulse animasyonu kf-zoom animasyonunun yerini alır, dolayısıyla ilk yakınlaştırmayı göremeyeceğiz ve beklenen ölçeği 1,2'ye alamayacağız. Eklenecek animasyon kompozisyonunu ayarlayarak tarayıcıya her iki animasyonu da birleştirmesini söyleriz. Bu bize istediğimiz sonucu verir. .bileşen-iki { animasyon kompozisyonu: ekle; }
Amit Sheen'in yazdığı Pen Keyframes Tokens - Demo 8'e [çatallı] bakın. Bu yaklaşım, etkileri aynı özellik üzerinde birleştirmek istediğimiz çoğu durumda işe yarar. Animasyonları statik özellik değerleriyle birleştirmemiz gerektiğinde de kullanışlıdır. Örneğin, onu tam olarak istediğimiz yere konumlandırmak için Translate özelliğini kullanan bir öğemiz varsa ve sonra onu kf-slide-in anahtar kareleriyle canlandırmak istersek, animasyon-kompozisyon olmadan kötü görünür bir sıçrama elde ederiz. Amit Sheen tarafından yazılan Pen Keyframes Tokens - Demo 9'a [çatallı] bakın. Eklenecek animasyon kompozisyonu ayarlandığında, animasyon mevcut olanla sorunsuz bir şekilde birleştirilir.böylece öğe yerinde kalır ve beklendiği gibi canlanır. Animasyon Kademeli Birden fazla animasyonu yönetmenin başka bir yolu da onları "kademeli" hale getirmektir; yani ikinci animasyonu, birincisi bittikten biraz sonra başlatmaktır. Bu her durumda işe yarayan bir çözüm değildir ancak giriş animasyonu ve ardından sürekli bir animasyon uyguladığımızda kullanışlıdır. /* solma + opaklık darbesi */ .bildirim { animasyon: kf-fade-in 2'li çıkış kolaylığı, kf-pulse 0,5 sn 2 sn giriş-çıkış sonsuz alternatif; --kf-darbe-opaklığı-to: 0,5; }
Amit Sheen tarafından yazılan Pen Keyframes Tokens - Demo 10'a [çatallı] bakın. Sipariş Önemlidir Çalıştığımız animasyonların büyük bir kısmı transform özelliğini kullanıyor. Çoğu durumda bu daha uygundur. Ayrıca dönüşüm animasyonları GPU ile hızlandırılabildiğinden performans avantajına da sahiptir. Ancak dönüşümleri kullanırsak dönüşümlerimizi gerçekleştirdiğimiz sıranın önemli olduğunu kabul etmemiz gerekir. Çok fazla. Şu ana kadar ana karelerimizde bireysel dönüşümler kullandık. Spesifikasyonlara göre bunlar her zaman sabit bir sırayla uygulanır: önce öğe çevrilir, sonra döndürülür ve ölçeklenir. Bu mantıklıdır ve çoğumuzun beklediği şeydir. Ancak transform özelliğini kullanırsak fonksiyonların yazılma sırası, uygulanma sırasıdır. Bu durumda bir şeyi X ekseninde 100 piksel hareket ettirip sonra 45 derece döndürsek, bu onu önce 45 derece döndürüp sonra 100 piksel hareket ettirmekle aynı şey değildir. /* Pembe kare: Önce çevir, sonra döndür */ .örnek-bir { dönüştürme: TranslateX(100px) döndürme(45 derece); }
/* Yeşil kare: Önce döndür, sonra çevir */ .örnek-iki { dönüştürme: döndürme(45 derece) çeviriX(100 piksel); }
Amit Sheen tarafından yazılan Pen Keyframes Tokens - Demo 11'e [çatallı] bakın. Ancak dönüşüm sırasına göre, tüm bireysel dönüşümler (ana kare belirteçleri için kullandığımız her şey) dönüşüm işlevlerinden önce gerçekleşir. Bu, transform özelliğinde ayarladığınız her şeyin animasyonlardan sonra gerçekleşeceği anlamına gelir. Ancak örneğin kf-spin anahtar kareleriyle birlikte çeviriyi ayarlarsanız çeviri animasyondan önce gerçekleşir. Henüz kafan mı karıştı? Bu, aşağıdaki durumda olduğu gibi statik değerlerin aynı animasyon için farklı sonuçlara neden olabileceği durumlara yol açar:
/* Her iki döndürücü için ortak animasyon */ .döndürücü { animasyon: kf-spin 1s doğrusal sonsuz; }
/* Pembe döndürücü: döndürmeden önce çevir (bireysel dönüşüm) */ .spinner-pembe { tercüme: %100 %50; }
/* Yeşil döndürücü: döndür ve çevir (işlev sırası) */ .spinner-yeşil { dönüştürme: tercüme et (%100, %50); }
Amit Sheen tarafından yazılan Pen Keyframes Tokens - Demo 12'ye [çatallı] bakın. İlk döndürücünün (pembe) kf-spin dönüşünden önce gerçekleşen bir çeviri aldığını, böylece önce yerine hareket ettiğini ve sonra döndüğünü görebilirsiniz. İkinci döndürücü (yeşil), bireysel dönüşümden sonra gerçekleşen bir çeviri() işlevi alır, böylece öğe önce döner, sonra mevcut açısına göre hareket eder ve bu geniş yörünge efektini elde ederiz. Hayır, bu bir hata değil. Bu, CSS hakkında bilmemiz gereken ve birden fazla animasyon veya birden fazla dönüşümle çalışırken aklımızda tutmamız gereken şeylerden sadece bir tanesidir. Gerekirse, döndürme() işlevini kullanarak öğeleri döndüren ek bir kf-spin-alt anahtar kareleri kümesi de oluşturabilirsiniz. Azaltılmış Hareket Alternatif anahtar karelerden bahsederken “animasyon yok” seçeneğini de göz ardı edemeyiz. Anahtar kare belirteçlerini kullanmanın en büyük avantajlarından biri erişilebilirliğin eklenebilmesidir ve bunu yapmak aslında oldukça kolaydır. Anahtar karelerimizi erişilebilirliği göz önünde bulundurarak tasarlayarak, azaltılmış hareketi tercih eden kullanıcıların, ekstra çalışma veya kod çoğaltma olmadan daha sorunsuz, daha az dikkat dağıtıcı bir deneyim yaşamasını sağlayabiliriz. "Azaltılmış Hareket"in tam anlamı bir animasyondan diğerine ve projeden projeye biraz değişebilir, ancak akılda tutulması gereken birkaç önemli nokta şunlardır: Anahtar Kareleri Sessize Alma Bazı animasyonlar yumuşatılabilir veya yavaşlatılabilirken, hareketin azaltılması istendiğinde tamamen kaybolması gereken başka animasyonlar da vardır. Darbe animasyonları iyi bir örnektir. Bu animasyonların azaltılmış hareket modunda çalışmadığından emin olmak için bunları uygun medya sorgusuna sarmamız yeterlidir.
@media (azaltılmış hareketi tercih eder: tercih yok) { @keyfrmaes kf-nabız { {'den ölçek: var(--kf-pulse-scale-from, 1); opaklık: var(--kf-pulse-opacity-from, 1); } {'e ölçek: var(--kf-darbe-ölçek-to, 1); opaklık:var(--kf-pulse-opacity-to, 1); } } }
Bu, azaltılmış hareketi azaltma seçeneğini ayarlayan kullanıcıların animasyonu görmemesini ve tercihlerine uygun bir deneyim yaşamasını sağlar. Anında Giriş Giriş animasyonları gibi kolayca kaldıramayacağımız bazı anahtar kareler var. Değer değişmeli, canlanmalı; aksi halde öğe doğru değerlere sahip olmayacaktır. Ancak azaltılmış harekette başlangıç değerinden bu geçişin anında olması gerekir. Bunu başarmak için değerin hemen son duruma atladığı ekstra bir anahtar kare kümesi tanımlayacağız. Bunlar varsayılan anahtar karelerimiz olur. Ardından, tıpkı önceki örnekte olduğu gibi, tercihler-azaltılmış hareket için tercihsiz olarak ayarlanmış bir medya sorgusunun içine normal anahtar kareleri ekleyeceğiz. /* hareketi azaltmak için anında devreye girin */ @keyframes kf-zoom { itibaren { ölçek: var(--kf-zoom-to, 1); } }
@media (azaltılmış hareketi tercih eder: tercih yok) { /* Orijinal yakınlaştırma anahtar kareleri */ @keyframes kf-zoom { {'den ölçek: var(--kf-zoom-from, 0,8); } {'e ölçek: var(--kf-zoom-to, 1); } } }
Bu şekilde, azaltılmış hareketi tercih eden kullanıcılar, öğenin anında son halinde göründüğünü görürken, diğer herkes animasyonlu geçişi görecektir. Yumuşak Yaklaşım Biraz hareketi korumak istediğimiz ancak orijinal animasyondan çok daha yumuşak ve sakin olduğu durumlar var. Örneğin, sıçrama girişini yumuşak bir geçişle değiştirebiliriz.
@keyframes kf-bounce { /* Azaltılmış hareket için yumuşak geçiş */ }
@media (azaltılmış hareketi tercih eder: tercih yok) { @keyframes kf-bounce { /* Orijinal geri dönen ana kareler */ } }
Artık, azaltılmış hareket özelliği etkin olan kullanıcılar, bir görünüm hissine sahip olmaya devam ediyor, ancak bu, sıçrama veya elastik animasyonun yoğun hareketi olmadan oluyor. Yapı taşları yerinde olduğunda, bir sonraki soru bunların nasıl gerçek iş akışının bir parçası haline getirileceğidir. Esnek anahtar kareler yazmak bir şeydir, ancak bunları büyük bir projede güvenilir hale getirmek, zor yoldan öğrenmem gereken birkaç stratejiyi gerektirir. Uygulama Stratejileri ve En İyi Uygulamalar Anahtar kare belirteçlerinden oluşan sağlam bir kütüphaneye sahip olduğumuzda asıl zorluk, bunları günlük işlere nasıl aktaracağımızdır.
Tüm ana kareleri bir kerede bırakıp sorunun çözüldüğünü beyan etmek cazip geliyor, ancak pratikte en iyi sonuçların kademeli olarak benimsenmeyle geldiğini buldum. Soldurma veya kaydırma gibi en yaygın animasyonlarla başlayın. Bunlar, büyük yeniden yazmalar gerektirmeden anında değer gösteren kolay kazançlardır. Adlandırma da dikkat edilmesi gereken bir diğer noktadır. Tutarlı bir önek veya ad alanı, hangi animasyonların simge, hangilerinin yerel tek seferlik olduğunu açıkça ortaya koyar. Ayrıca kazara çarpışmaları önler ve yeni ekip üyelerinin paylaşılan sistemi bir bakışta tanımasına yardımcı olur. Dokümantasyon kodun kendisi kadar önemlidir. Her bir anahtar kare belirtecinin üzerine kısa bir yorum bile daha sonra saatlerce tahmin yapma zahmetinden kurtarabilir. Bir geliştirici, token dosyasını açabilmeli, ihtiyaç duyduğu efekti tarayabilmeli ve kullanım modelini doğrudan kendi bileşenine kopyalayabilmelidir. Bu yaklaşımı çabaya değer kılan şey esnekliktir. Mantıklı özel özellikleri ortaya çıkararak ekiplere, sistemi bozmadan animasyonu uyarlamaları için alan sağlıyoruz. Aynı zamanda işleri aşırı karmaşıklaştırmamaya çalışın. Önemli olan düğmeleri sağlayın ve geri kalanını düşünceli tutun. Son olarak erişilebilirliği unutmayın. Her animasyonun azaltılmış hareket alternatifine ihtiyacı yoktur, ancak çoğunun ihtiyacı vardır. Bu ayarlamaları erkenden yapmak, onları daha sonra yenilemek zorunda kalmayacağımız anlamına gelir ve bu, kullanıcılarımızın bundan hiç bahsetmeseler bile fark edecekleri düzeyde bir özeni gösterir.
Deneyimlerime göre, anahtar kare belirteçlerini tasarım belirteçleri iş akışımızın bir parçası olarak ele almak, onların kalıcı olmasını sağlayan şeydir. Yerlerine yerleştirildiklerinde özel efekt gibi hissetmeyi bırakırlar ve ürünün hareket etme ve tepki verme şeklinin doğal bir uzantısı olan tasarım dilinin bir parçası haline gelirler. Kapanış Animasyonlar, arayüz oluşturmanın en eğlenceli kısımlarından biri olabilir, ancak yapı olmadan en büyük hayal kırıklığı kaynaklarından biri de olabilirler. Anahtar kareleri simge olarak ele alarak, genellikle dağınık ve yönetilmesi zor olan bir şeyi alıp net, öngörülebilir bir sisteme dönüştürürsünüz. Gerçek değer yalnızca birkaç satır kod kaydetmek değildir. Soldurma, kaydırma, yakınlaştırma veya döndürme işlemlerini kullandığınızda bunun proje genelinde nasıl davranacağını tam olarak bildiğinize güvenebilirsiniz. Sonsuz varyasyonların kaosu olmadan, özel özelliklerden gelen esnekliktedir. Ve bu, eklenmek yerine temelin içine yerleştirilmiş erişilebilirliktir.sonradan akla gelen bir düşünce. Bu fikirlerin farklı ekiplerde ve farklı kod tabanlarında çalıştığını gördüm ve model her zaman aynı. Belirteçler yerine oturduğunda, ana kareler dağınık bir hileler koleksiyonu olmaktan çıkar ve tasarım dilinin bir parçası haline gelir. Ürünün daha kasıtlı, daha tutarlı ve daha canlı görünmesini sağlarlar. Bu makaleden alacağınız bir şey varsa o da şu olsun: Animasyonlar, renklere, tipografiye ve aralıklara gösterdiğimiz özen ve yapının aynısını hak ediyor. Anahtar kare belirteçlerine yapılan küçük bir yatırım, arayüzünüz her hareket ettiğinde karşılığını verir.