Bayangkan ini: Anda bergabung dengan proyek baru, mendalami basis kode, dan dalam beberapa jam pertama, Anda menemukan sesuatu yang sangat familier. Tersebar di seluruh stylesheet, Anda menemukan beberapa definisi @keyframes untuk animasi dasar yang sama. Tiga efek fade-in yang berbeda, dua atau tiga variasi slide, beberapa animasi zoom, dan setidaknya dua animasi putaran yang berbeda karena, mengapa tidak? @keyframes pulsa { dari { skala: 1; } ke { skala: 1.1; } }

@keyframes pulsa lebih besar { 0%, 20%, 100% { skala: 1; } 10%, 40% { skala: 1.2; } }

Jika skenario ini terdengar familier, Anda tidak sendirian. Berdasarkan pengalaman saya di berbagai proyek, salah satu pencapaian cepat paling konsisten yang dapat saya capai adalah mengkonsolidasikan dan menstandardisasi keyframe. Ini menjadi pola yang dapat diandalkan sehingga saya sekarang menantikan pembersihan ini sebagai salah satu tugas pertama saya pada basis kode baru. Logika Dibalik Kekacauan Redundansi ini sangat masuk akal jika Anda memikirkannya. Kita semua menggunakan animasi dasar yang sama dalam pekerjaan kita sehari-hari: fade, slide, zoom, spin, dan efek umum lainnya. Animasi ini cukup mudah, dan mudah untuk menyiapkan definisi @keyframes dengan cepat untuk menyelesaikan pekerjaan. Tanpa sistem animasi terpusat, pengembang secara alami menulis keyframe ini dari awal, tanpa menyadari bahwa animasi serupa sudah ada di tempat lain dalam basis kode. Hal ini sangat umum terjadi ketika bekerja dalam arsitektur berbasis komponen (yang sebagian besar dari kita lakukan saat ini), karena tim sering kali bekerja secara paralel di berbagai bagian aplikasi. Hasilnya? Kekacauan animasi. Masalah Kecil Masalah yang paling jelas dengan duplikasi keyframe adalah waktu pengembangan yang terbuang dan pembengkakan kode yang tidak perlu. Beberapa definisi bingkai utama berarti banyak tempat untuk diperbarui ketika persyaratan berubah. Perlu menyesuaikan waktu animasi fade Anda? Anda harus mencari setiap contoh di basis kode Anda. Ingin menstandarisasi fungsi easing? Semoga berhasil menemukan semua variasinya. Penggandaan poin pemeliharaan ini membuat pembaruan animasi sederhana menjadi tugas yang memakan waktu. Masalah yang Lebih Besar Duplikasi keyframe ini menciptakan masalah yang lebih berbahaya yang tersembunyi di balik permukaan: jebakan cakupan global. Bahkan ketika bekerja dengan arsitektur berbasis komponen, keyframe CSS selalu didefinisikan dalam lingkup global. Ini berarti semua keyframe berlaku untuk semua komponen. Selalu. Ya, animasi Anda tidak selalu menggunakan bingkai utama yang Anda tentukan di komponen Anda. Ia menggunakan keyframe terakhir yang cocok dengan nama yang sama persis yang dimuat ke dalam cakupan global. Selama semua bingkai utama Anda identik, ini mungkin tampak seperti masalah kecil. Namun saat Anda ingin menyesuaikan animasi untuk kasus penggunaan tertentu, Anda akan mendapat masalah, atau lebih buruk lagi, Andalah yang menyebabkannya. Animasi Anda tidak akan berfungsi karena komponen lain dimuat setelah komponen Anda, menimpa keyframe Anda, atau komponen Anda dimuat terakhir kali dan secara tidak sengaja mengubah perilaku animasi untuk setiap komponen lain menggunakan nama keyframe tersebut, dan Anda mungkin tidak menyadarinya. Berikut ini contoh sederhana yang menunjukkan masalahnya: .komponen-satu { /* gaya komponen */ animasi: pulsa 1 detik kemudahan masuk-keluar alternatif tak terbatas; }

/* definisi @keyframes ini tidak akan berfungsi */ @keyframes pulsa { dari { skala: 1; } ke { skala: 1.1; } }

/* nanti di kode... */

.komponen-dua { /* gaya komponen */ animasi: pulsa 1s kemudahan masuk-keluar tak terbatas; }

/* keyframe ini akan diterapkan pada kedua komponen */ @keyframes pulsa { 0%, 20%, 100% { skala: 1; } 10%, 40% { skala: 1.2; } }

Kedua komponen menggunakan nama animasi yang sama, tetapi definisi @keyframes kedua menimpa definisi pertama. Sekarang komponen satu dan komponen dua akan menggunakan keyframe kedua, terlepas dari komponen mana yang menentukan keyframe mana. Lihat Token Keyframes Pena - Demo 1 [bercabang] oleh Amit Sheen. Bagian terburuknya? Ini sering kali berfungsi dengan baik dalam pengembangan lokal tetapi rusak secara misterius dalam produksi ketika proses pembangunan mengubah urutan pemuatan stylesheet Anda. Anda akan mendapatkan animasi yang berperilaku berbeda bergantung pada komponen mana yang dimuat dan dalam urutan apa. Solusinya: Keyframe Terpadu Jawaban atas kekacauan ini ternyata sangat sederhana: bingkai utama dinamis yang telah ditentukan sebelumnya disimpan dalam lembar gaya bersama. Daripada membiarkan setiap komponen menentukan animasinya sendiri, kami membuat keyframe terpusat yang terdokumentasi dengan baik, mudahdigunakan, dapat dipelihara, dan disesuaikan dengan kebutuhan spesifik proyek Anda. Anggap saja sebagai token bingkai utama. Sama seperti kita menggunakan token untuk warna dan spasi, dan banyak dari kita sudah menggunakan token untuk properti animasi, seperti fungsi durasi dan easing, mengapa tidak menggunakan token untuk keyframe juga? Pendekatan ini dapat berintegrasi secara alami dengan alur kerja token desain apa pun yang Anda gunakan saat ini, sekaligus menyelesaikan masalah kecil (duplikasi kode) dan masalah yang lebih besar (konflik cakupan global) sekaligus. Idenya sederhana: ciptakan satu sumber kebenaran untuk semua animasi umum kita. Stylesheet bersama ini berisi bingkai utama yang dibuat dengan cermat yang mencakup pola animasi yang sebenarnya digunakan proyek kami. Tidak perlu lagi menebak apakah animasi fade sudah ada di suatu tempat di basis kode kami. Tidak ada lagi animasi yang tertimpa secara tidak sengaja dari komponen lain. Namun inilah kuncinya: ini bukan sekadar animasi salin-tempel statis. Mereka dirancang agar dinamis dan dapat disesuaikan melalui properti kustom CSS, memungkinkan kami menjaga konsistensi sambil tetap memiliki fleksibilitas untuk mengadaptasi animasi ke kasus penggunaan tertentu, seperti jika Anda memerlukan animasi “pulsa” yang sedikit lebih besar di satu tempat. Membangun Token Keyframes Pertama Salah satu hal pertama yang harus kita atasi adalah animasi “fade-in”. Dalam salah satu proyek terbaru saya, saya menemukan lebih dari selusin definisi fade-in yang terpisah, dan ya, semuanya hanya menganimasikan opacity dari 0 ke 1. Jadi, mari buat stylesheet baru, beri nama kf-tokens.css, impor ke proyek kita, dan tempatkan keyframe dengan komentar yang tepat di dalamnya. /* keyframes-tokens.css */

/* * Fade In - animasi pintu masuk memudar * Penggunaan: animasi: kf-fade-in 0,3 detik ease-out; */ @keyframes kf-fade-in { dari { opacity: 0; } ke { opacity: 1; } }

Deklarasi @keyframes tunggal ini menggantikan semua animasi fade-in yang tersebar di seluruh basis kode kami. Bersih, sederhana, dan dapat diterapkan secara global. Dan sekarang setelah token ini ditentukan, kita dapat menggunakannya dari komponen mana pun di seluruh proyek kita: .modal { animasi: kf-fade-in 0,3 detik dengan kemudahan; }

.keterangan alat { animasi: kf-fade-in 0,2 detik kemudahan masuk-keluar; }

.pemberitahuan { animasi: kf-fade-in 0,5 detik dengan kemudahan; }

Lihat Token Pen Keyframes - Demo 2 [bercabang] oleh Amit Sheen. Catatan: Kami menggunakan awalan kf- di semua nama @keyframes kami. Awalan ini berfungsi sebagai namespace yang mencegah konflik penamaan dengan animasi yang ada di proyek dan segera memperjelas bahwa keyframe ini berasal dari file token keyframes kami. Membuat Slide Dinamis Keyframe kf-fade-in berfungsi dengan baik karena sederhana dan hanya ada sedikit ruang untuk mengacaukan segalanya. Namun, dalam animasi lain, kita harus lebih dinamis, dan di sini kita dapat memanfaatkan kekuatan luar biasa dari properti kustom CSS. Di sinilah token keyframe benar-benar bersinar dibandingkan dengan animasi statis yang tersebar. Mari kita ambil skenario umum: animasi “slide-in”. Tapi meluncur dari mana? 100 piksel dari kanan? 50% dari kiri? Haruskah itu masuk dari atas layar? Atau mungkin melayang dari bawah? Begitu banyak kemungkinannya, namun alih-alih membuat keyframe terpisah untuk setiap arah dan setiap variasi, kita dapat membuat satu token fleksibel yang beradaptasi dengan semua skenario: /* * Slide In - animasi slide terarah * Gunakan --kf-slide-from untuk mengontrol arah * Default: meluncur dari kiri (-100%) * Penggunaan: * animasi: kf-slide-in 0,3 detik dengan kemudahan; * --kf-slide-dari: -100px 0; // geser dari kiri * --kf-slide-from: 100px 0; // geser dari kanan * --kf-slide-dari: 0 -50 piksel; // geser dari atas */

@keyframes kf-slide-in { dari { terjemahkan: var(--kf-slide-from, -100% 0); } ke { terjemahkan: 0 0; } }

Sekarang kita dapat menggunakan token @keyframes ini untuk arah slide apa pun hanya dengan mengubah properti khusus --kf-slide-from: .bilah sisi { animasi: kf-slide-in 0,3 detik dengan kemudahan; /* Menggunakan nilai default: meluncur dari kiri */ }

.pemberitahuan { animasi: kf-slide-in 0,4 detik dengan kemudahan; --kf-slide-dari: 0 -50 piksel; /* geser dari atas */ }

.modal { animasi: kf-fade-in 0,5 detik, kf-slide-in 0,5s kubik-bezier(0,34, 1,56, 0,64, 1); --kf-slide-dari: 50px 50px; /* geser dari kanan bawah */ }

Pendekatan ini memberi kita fleksibilitas luar biasa sekaligus menjaga konsistensi. Satu deklarasi keyframe, kemungkinan tak terbatas. Lihat Token Pen Keyframes - Demo 3 [bercabang] oleh Amit Sheen. Dan jika kita ingin membuat animasi kita lebih fleksibel, memungkinkan efek “slide-out” juga, kita bisacukup tambahkan properti khusus --kf-slide-to, serupa dengan yang akan kita lihat di bagian berikutnya. Bingkai Utama Zoom Dua Arah Animasi umum lainnya yang diduplikasi di seluruh proyek adalah efek “zoom”. Baik itu peningkatan skala halus untuk pesan toast, pembesaran dramatis untuk modals, atau efek penurunan skala halus untuk judul, animasi zoom ada di mana-mana. Daripada membuat keyframe terpisah untuk setiap nilai skala, mari kita buat satu set keyframe kf-zoom yang fleksibel:

/* * Zoom - animasi skala * Gunakan --kf-zoom-from dan --kf-zoom-to untuk mengontrol nilai skala * Default: memperbesar dari 80% hingga 100% (0,8 hingga 1) * Penggunaan: * animasi: kf-zoom 0,2 detik dengan kemudahan; * --kf-zoom-dari: 0,5; --kf-zoom-ke: 1; // perbesar dari 50% menjadi 100% * --kf-zoom-dari: 1; --kf-memperbesar-ke: 0; // perbesar dari 100% menjadi 0% * --kf-zoom-dari: 1; --kf-zoom-ke: 1.1; // perbesar dari 100% menjadi 110% */

@keyframes kf-zoom { dari { skala: var(--kf-zoom-from, 0.8); } ke { skala: var(--kf-zoom-to, 1); } }

Dengan satu definisi, kita dapat mencapai variasi zoom apa pun yang kita perlukan: .roti panggang { animasi: kf-slide-in 0,2 detik, kf-zoom kemudahan 0,4 detik; --kf-slide-dari: 0 100%; /* geser dari atas */ /* Menggunakan zoom default: skala dari 80% hingga 100% */ }

.modal { animasi: kf-zoom 0,3s kubik-bezier(0,34, 1,56, 0,64, 1); --kf-zoom-dari: 0; /* zoom dramatis dari 0% hingga 100% */ }

.heading { animasi: kf-fade-in 2s, kf-zoom 2s kemudahan masuk; --kf-zoom-dari: 1.2; --kf-zoom-ke: 0,8; /* turunkan skala secara perlahan */ }

Default 0,8 (80%) berfungsi sempurna untuk sebagian besar elemen UI, seperti pesan roti panggang dan kartu, namun tetap mudah disesuaikan untuk kasus-kasus khusus. Lihat Token Pen Keyframes - Demo 4 [bercabang] oleh Amit Sheen. Anda mungkin memperhatikan sesuatu yang menarik dalam contoh terbaru: kami telah menggabungkan animasi. Salah satu keuntungan utama bekerja dengan token @keyframes adalah token tersebut dirancang untuk berintegrasi secara mulus satu sama lain. Komposisi halus ini disengaja, bukan kebetulan. Kita akan membahas komposisi animasi secara lebih rinci nanti, termasuk di mana komposisi tersebut dapat menjadi masalah, namun sebagian besar kombinasi bersifat langsung dan mudah diterapkan. Catatan: Saat menulis artikel ini, dan mungkin karena menulisnya, saya mendapati diri saya memikirkan kembali keseluruhan ide animasi pintu masuk. Dengan semua kemajuan terkini dalam CSS, apakah kita masih membutuhkannya? Untungnya, Adam Argyle mengeksplorasi pertanyaan yang sama dan mengungkapkannya dengan cemerlang di blognya. Hal ini tidak bertentangan dengan apa yang tertulis di sini, namun ini menghadirkan pendekatan yang patut dipertimbangkan, terutama jika proyek Anda sangat bergantung pada animasi masuk. Animasi Berkelanjutan Meskipun animasi masuk, seperti “memudar”, “slide”, dan “zoom” terjadi satu kali lalu berhenti, animasi berkelanjutan berulang tanpa batas waktu untuk menarik perhatian atau menunjukkan aktivitas yang sedang berlangsung. Dua animasi kontinu paling umum yang saya temui adalah “spin” (untuk memuat indikator) dan “pulse” (untuk menyorot elemen penting). Animasi ini menghadirkan tantangan unik dalam pembuatan token bingkai utama. Tidak seperti animasi masuk yang biasanya berpindah dari satu keadaan ke keadaan lain, animasi berkelanjutan harus sangat dapat disesuaikan pola perilakunya. Dokter Putar Setiap proyek tampaknya menggunakan beberapa animasi putaran. Beberapa berputar searah jarum jam, yang lain berlawanan arah jarum jam. Beberapa melakukan satu putaran 360 derajat, yang lain melakukan beberapa putaran untuk efek yang lebih cepat. Daripada membuat keyframe terpisah untuk setiap variasi, mari buat satu putaran fleksibel yang menangani semua skenario:

/* * Putar - animasi rotasi * Gunakan --kf-spin-from dan --kf-spin-to untuk mengontrol rentang rotasi * Gunakan --kf-spin-turns untuk mengontrol jumlah rotasi * Default: berputar dari 0 derajat hingga 360 derajat (1 putaran penuh) * Penggunaan: * animasi: kf-spin 1s linier tak terbatas; * --kf-spin-turns: 2; // 2 putaran penuh * --kf-spin-dari: 0 derajat; --kf-spin-ke: 180 derajat; // setengah putaran * --kf-spin-dari: 0 derajat; --kf-spin-ke: -360deg; // berlawanan arah jarum jam */

@keyframes kf-spin { dari { putar: var(--kf-spin-from, 0deg); } ke { putar: calc(var(--kf-spin-from, 0deg) + var(--kf-spin-to, 360deg) * var(--kf-spin-turns, 1)); } }

Sekarang kita dapat membuat variasi putaran apa pun yang kita suka:

.memuat-spinner { animasi: kf-spin 1s linier tak terbatas; /* Menggunakan default: berputar dari 0 derajat ke 360 derajat */ }

.pemuat cepat { animasi: kf-spin 1.2s kemudahan masuk-keluar alternatif tak terbatas; --kf-putaran-putaran: 3; /* 3 putaran penuh untuk setiap arah per siklus*/ }

.steped-reverse { animasi: kf-spin 1,5 detik langkah (8) tak terbatas; --kf-spin-ke: -360deg; /* berlawanan arah jarum jam */ }

.goyangan halus { animasi: kf-spin 2s kemudahan masuk-keluar alternatif tak terbatas; --kf-spin-dari: -16deg; --kf-spin-ke: 32 derajat; /* menggoyangkan 36 derajat: antara -18 derajat dan +18 derajat */ }

Lihat Token Pen Keyframes - Demo 5 [bercabang] oleh Amit Sheen. Keunggulan dari pendekatan ini adalah keyframe yang sama berfungsi untuk memuat spinner, memutar ikon, efek goyangan, dan bahkan animasi multi-putaran yang kompleks. Paradoks Denyut Nadi Animasi pulsa lebih rumit karena dapat “menggerakkan” properti yang berbeda. Beberapa menentukan skala, yang lain menentukan opacity, dan beberapa properti warna seperti kecerahan atau saturasi. Daripada membuat keyframe terpisah untuk setiap properti, kita dapat membuat keyframe yang berfungsi dengan properti CSS apa pun. Berikut ini contoh keyframe pulsa dengan opsi skala dan opacity:

/* * Pulsa - animasi berdenyut * Gunakan --kf-pulse-scale-from dan --kf-pulse-scale-to untuk mengontrol rentang skala * Gunakan --kf-pulse-opacity-from dan --kf-pulse-opacity-to untuk mengontrol rentang opacity * Default: tidak ada pulsa (semua nilai 1) * Penggunaan: * animasi: kf-pulse 2s kemudahan masuk-keluar alternatif tak terbatas; * --kf-skala-pulsa-dari: 0,95; --kf-skala-pulsa-ke: 1,05; // skala pulsa * --kf-pulse-opacity-from: 0,7; --kf-pulsa-opacity-ke: 1; // pulsa opacity */

@keyframes kf-pulsa { dari { skala: var(--kf-skala-pulsa-dari, 1); opacity: var(--kf-pulse-opacity-from, 1); } ke { skala: var(--kf-pulse-scale-to, 1); opacity: var(--kf-pulse-opacity-to, 1); } }

Ini menciptakan pulsa fleksibel yang dapat menganimasikan beberapa properti: .ajakan bertindak { animasi: kf-pulse 0,6 detik alternatif tak terbatas; --kf-pulsa-opacity-dari: 0,5; /* pulsa opasitas */ }

.notifikasi-titik { animasi: kf-pulse 0,6 detik kemudahan masuk-keluar alternatif tak terbatas; --kf-skala-pulsa-dari: 0,9; --kf-skala-pulsa-ke: 1.1; /* skala pulsa */ }

.teks-sorot { animasi: kf-pulse 1,5s ease-out tak terbatas; --kf-skala-pulsa-dari: 0,8; --kf-pulsa-opacity-dari: 0,2; /* skala dan opasitas pulsa */ }

Lihat Token Pen Keyframes - Demo 6 [bercabang] oleh Amit Sheen. Keyframe kf-pulse tunggal ini dapat menangani segalanya mulai dari perebutan perhatian halus hingga sorotan dramatis, sekaligus mudah untuk disesuaikan. Pelonggaran Tingkat Lanjut Salah satu hal hebat tentang penggunaan token keyframe adalah betapa mudahnya memperluas perpustakaan animasi kami dan memberikan efek yang sebagian besar pengembang tidak akan repot-repot menulisnya dari awal, seperti elastis atau pantulan. Berikut adalah contoh token keyframe “bounce” sederhana yang menggunakan properti khusus --kf-bounce-from untuk mengontrol ketinggian lompatan. /* * Bounce - animasi masuk yang memantul * Gunakan --kf-bounce-from untuk mengontrol ketinggian lompatan * Default: melompat dari 100vh (di luar layar) * Penggunaan: * animasi: kemudahan kf-bounce 3s; * --kf-bounce-from: 200 piksel; // melompat dari ketinggian 200px */

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

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

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

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

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

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

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

22%, 45%, 64%, 79%, 90%, 97%, 100% { terjemahkan: 0 0; fungsi pengaturan waktu animasi: kemudahan; } }

Animasi seperti "elastis" sedikit lebih rumit karena perhitungan di dalam bingkai utama. Kita perlu mendefinisikan --kf-elastic-from-X dan --kf-elastic-from-Y secara terpisah (keduanya opsional), dan bersama-sama memungkinkan kita membuat pintu masuk elastis dari titik mana pun di layar.

/* * Elastic In - animasi masuk elastis * Gunakan --kf-elastic-from-X dan --kf-elastic-from-Y untuk mengontrol posisi awal * Default: masuk dari tengah atas (0, -100vh) * Penggunaan: * animasi: kf-elastic-in 2s ease-in-out keduanya; * --kf-elastis-dari-X: -50px; * --kf-elastis-dari-Y: -200px; // masuk dari (-50px, -200px) */

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

16% { terjemahkan: calc(var(--kf-elastic-from-X, -50vw) * -0.3227) calc(var(--kf-elastic-from-Y, 0px) * -0.3227); }

28% { terjemahkan: calc(var(--kf-elastis-dari-X, -50vw) * 0,1312)calc(var(--kf-elastis-dari-Y, 0px) * 0,1312); }

44% { terjemahkan: calc(var(--kf-elastic-from-X, -50vw) * -0.0463) calc(var(--kf-elastic-from-Y, 0px) * -0.0463); }

59% { terjemahkan: calc(var(--kf-elastic-from-X, -50vw) * 0.0164) calc(var(--kf-elastic-from-Y, 0px) * 0.0164); }

73% { terjemahkan: calc(var(--kf-elastic-from-X, -50vw) * -0.0058) calc(var(--kf-elastic-from-Y, 0px) * -0.0058); }

88% { terjemahkan: calc(var(--kf-elastic-from-X, -50vw) * 0,0020) calc(var(--kf-elastic-from-Y, 0px) * 0,0020); }

100% { terjemahkan: 0 0; } }

Pendekatan ini memudahkan penggunaan kembali dan penyesuaian bingkai utama tingkat lanjut di seluruh proyek kami, hanya dengan mengubah satu properti khusus.

.pantulan-dan-zoom { animasi: kf-bounce 3s kemudahan masuk, kf-zoom 3s linier; --kf-zoom-dari: 0; }

.pantulan-dan-slide { komposisi animasi: tambahkan; /* Kedua animasi tersebut menggunakan terjemahan */ animasi: kf-bounce 3s kemudahan masuk, kf-slide-in 3 detik kemudahan; --kf-slide-dari: -200 piksel; }

.elastis-dalam { animasi: kf-elastic-in 2s ease-in-out keduanya; }

Lihat Token Pen Keyframes - Demo 7 [bercabang] oleh Amit Sheen. Hingga saat ini, kita telah melihat bagaimana kita dapat mengkonsolidasikan keyframe dengan cara yang cerdas dan efisien. Tentu saja, Anda mungkin ingin mengubah berbagai hal agar lebih sesuai dengan kebutuhan proyek Anda, namun kami telah membahas contoh beberapa animasi umum dan kasus penggunaan sehari-hari. Dan dengan adanya token keyframe ini, kami sekarang memiliki elemen penyusun yang kuat untuk membuat animasi yang konsisten dan dapat dipelihara di seluruh proyek. Tidak ada lagi duplikat keyframe, tidak ada lagi konflik cakupan global. Hanya cara yang bersih dan nyaman untuk menangani semua kebutuhan animasi kita. Namun pertanyaan sebenarnya adalah: Bagaimana kita menyusun elemen-elemen ini bersama-sama? Menyatukan Semuanya Kita telah melihat bahwa menggabungkan token keyframe dasar itu sederhana. Kita tidak memerlukan sesuatu yang istimewa selain mendefinisikan animasi pertama, menentukan animasi kedua, mengatur variabel sesuai kebutuhan, dan selesai. /* Memudar + menggeser masuk */ .roti panggang { animasi: kf-fade-in 0,4 detik, kf-slide-in 0,4s kubik-bezier(0,34, 1,56, 0,64, 1); --kf-slide-dari: 0 40 piksel; }

/* Memperbesar + memperkecil */ .modal { animasi: kf-fade-in 0,3 detik, kf-zoom 0,3s kubik-bezier(0,34, 1,56, 0,64, 1); --kf-zoom-dari: 0,7; --kf-zoom-ke: 1; }

/* Geser masuk + pulsa */ .pemberitahuan { animasi: kf-slide-in 0,5 detik, kf-pulse 1.2s kemudahan masuk-keluar alternatif tak terbatas; --kf-slide-dari: -100px 0; --kf-skala-pulsa-dari: 0,95; --kf-skala-pulsa-ke: 1,05; }

Kombinasi ini bekerja dengan baik karena setiap animasi menargetkan properti yang berbeda: opacity, transform (terjemahan/skala), dll. Namun terkadang ada konflik, dan kita perlu mengetahui alasannya dan bagaimana menanganinya. Saat dua animasi mencoba menganimasikan properti yang sama — misalnya, keduanya menganimasikan skala atau keduanya menganimasikan opacity — hasilnya tidak akan seperti yang Anda harapkan. Secara default, hanya satu animasi yang benar-benar diterapkan ke properti tersebut, yaitu animasi terakhir dalam daftar animasi. Ini adalah batasan bagaimana CSS menangani banyak animasi pada properti yang sama. Misalnya, ini tidak akan berfungsi sebagaimana mestinya karena hanya animasi kf-pulse yang akan diterapkan. .kombo-buruk { animasi: kf-zoom 0,5 detik ke depan, kf-pulsa 1,2 detik bergantian tak terbatas; --kf-zoom-dari: 0,5; --kf-zoom-ke: 1.2; --kf-skala-pulsa-dari: 0,8; --kf-skala-pulsa-ke: 1.1; }

Penambahan Animasi Cara paling sederhana dan langsung untuk menangani beberapa animasi yang memengaruhi properti yang sama adalah dengan menggunakan properti komposisi animasi. Pada contoh terakhir di atas, animasi kf-pulse menggantikan animasi kf-zoom, jadi kita tidak akan melihat zoom awal dan tidak akan mendapatkan skala yang diharapkan sebesar 1,2. Dengan mengatur komposisi animasi yang akan ditambahkan, kami memberi tahu browser untuk menggabungkan kedua animasi tersebut. Ini memberi kita hasil yang kita inginkan. .komponen-dua { komposisi animasi: tambahkan; }

Lihat Token Pen Keyframes - Demo 8 [bercabang] oleh Amit Sheen. Pendekatan ini bekerja dengan baik untuk sebagian besar kasus ketika kita ingin menggabungkan efek pada properti yang sama. Hal ini juga berguna ketika kita perlu menggabungkan animasi dengan nilai properti statis. Misalnya, jika kita memiliki elemen yang menggunakan properti terjemahan untuk memposisikannya tepat di tempat yang kita inginkan, dan kemudian kita ingin menganimasikannya dengan keyframe kf-slide-in, kita mendapatkan lompatan yang terlihat buruk tanpa komposisi animasi. Lihat Token Pen Keyframes - Demo 9 [bercabang] oleh Amit Sheen. Dengan komposisi animasi yang diatur untuk ditambahkan, animasi digabungkan dengan lancar dengan yang sudah adabertransformasi, sehingga elemen tetap di tempatnya dan bernyawa seperti yang diharapkan. Animasi Terhuyung-huyung Cara lain untuk menangani banyak animasi adalah dengan “mengatur” animasi tersebut — yaitu, memulai animasi kedua sedikit setelah animasi pertama selesai. Ini bukan solusi yang berhasil untuk setiap kasus, namun berguna ketika kita memiliki animasi masuk yang diikuti dengan animasi berkelanjutan. /* memudar + pulsa opacity */ .pemberitahuan { animasi: kf-fade-in 2s kemudahan keluar, kf-pulse 0,5s 2s kemudahan masuk-keluar alternatif tak terbatas; --kf-pulse-opacity-to: 0,5; }

Lihat Token Pen Keyframes - Demo 10 [bercabang] oleh Amit Sheen. Masalah Pesanan Sebagian besar animasi yang kami kerjakan menggunakan properti transform. Dalam kebanyakan kasus, ini lebih nyaman. Ini juga memiliki keunggulan kinerja karena animasi transformasi dapat dipercepat dengan GPU. Namun jika kita menggunakan transformasi, kita perlu menerima bahwa urutan transformasi yang kita lakukan itu penting. Banyak. Dalam bingkai utama kami sejauh ini, kami telah menggunakan transformasi individual. Menurut spesifikasinya, ini selalu diterapkan dalam urutan tetap: pertama, elemen diterjemahkan, lalu diputar, lalu diskalakan. Ini masuk akal dan merupakan apa yang diharapkan sebagian besar dari kita. Namun, jika kita menggunakan properti transform, urutan penulisan fungsi adalah urutan penerapannya. Dalam hal ini, jika kita memindahkan sesuatu sebesar 100 piksel pada sumbu X lalu memutarnya sebesar 45 derajat, tidak sama dengan memutarnya terlebih dahulu sebesar 45 derajat lalu memindahkannya sebesar 100 piksel. /* Kotak merah muda: Terjemahkan terlebih dahulu, lalu putar */ .contoh-satu { transformasi: TranslateX(100px) putar(45 derajat); }

/* Kotak hijau: Putar dulu, lalu terjemahkan */ .contoh-dua { transformasi: putar(45 derajat) TranslateX(100px); }

Lihat Token Pen Keyframes - Demo 11 [bercabang] oleh Amit Sheen. Namun menurut urutan transformasi, semua transformasi individual — semua yang kami gunakan untuk token bingkai utama — terjadi sebelum fungsi transformasi. Itu berarti apa pun yang Anda atur di properti transform akan terjadi setelah animasi. Namun jika Anda menyetel, misalnya, terjemahan bersama dengan bingkai utama kf-spin, terjemahan akan dilakukan sebelum animasi. Masih bingung?! Hal ini mengarah pada situasi di mana nilai statis dapat menyebabkan hasil berbeda untuk animasi yang sama, seperti dalam kasus berikut:

/* Animasi umum untuk kedua spinner */ .spinner { animasi: kf-spin 1s linier tak terbatas; }

/* Pemintal merah muda: terjemahkan sebelum memutar (transformasi individu) */ .spinner-merah muda { terjemahkan: 100% 50%; }

/* Pemintal hijau: putar lalu terjemahkan (urutan fungsi) */ .spinner-hijau { transformasi: terjemahkan(100%, 50%); }

Lihat Token Pen Keyframes - Demo 12 [bercabang] oleh Amit Sheen. Terlihat spinner pertama (merah muda) mendapat terjemahan yang terjadi sebelum putaran kf-spin, sehingga terlebih dahulu berpindah ke tempatnya lalu berputar. Pemintal kedua (hijau) mendapatkan fungsi Translate() yang terjadi setelah transformasi individu, sehingga elemen pertama berputar, lalu bergerak relatif terhadap sudutnya saat ini, dan kita mendapatkan efek orbit lebar. Tidak, ini bukan bug. Ini hanyalah salah satu hal yang perlu kita ketahui tentang CSS dan ingat ketika bekerja dengan banyak animasi atau banyak transformasi. Jika diperlukan, Anda juga dapat membuat satu set keyframe kf-spin-alt tambahan yang memutar elemen menggunakan fungsirotate(). Gerakan Berkurang Dan ketika kita berbicara tentang keyframe alternatif, kita tidak dapat mengabaikan opsi “tanpa animasi”. Salah satu keuntungan terbesar menggunakan token keyframe adalah aksesibilitasnya dapat ditingkatkan, dan sebenarnya cukup mudah dilakukan. Dengan merancang bingkai utama dengan mempertimbangkan aksesibilitas, kami dapat memastikan bahwa pengguna yang lebih menyukai gerakan yang dikurangi mendapatkan pengalaman yang lebih lancar dan tidak terlalu mengganggu, tanpa kerja ekstra atau duplikasi kode. Arti sebenarnya dari “Reduksi Gerakan” dapat berubah sedikit dari satu animasi ke animasi lainnya, dan dari proyek ke proyek, namun berikut adalah beberapa poin penting yang perlu diingat: Mematikan Keyframe Meskipun beberapa animasi dapat diperhalus atau diperlambat, ada animasi lain yang akan hilang sepenuhnya saat gerakan dikurangi diminta. Animasi pulsa adalah contoh yang bagus. Untuk memastikan animasi ini tidak berjalan dalam mode gerakan tereduksi, kita cukup membungkusnya dalam media query yang sesuai.

@media (lebih memilih gerakan yang dikurangi: tidak ada preferensi) { @keyfrmaes kf-pulsa { dari { skala: var(--kf-skala-pulsa-dari, 1); opacity: var(--kf-pulse-opacity-from, 1); } ke { skala: var(--kf-pulse-scale-to, 1); kegelapan:var(--kf-pulse-opacity-to, 1); } } }

Hal ini memastikan bahwa pengguna yang telah menyetel preferensi-gerakan yang dikurangi ke pengurangan tidak akan melihat animasi dan akan mendapatkan pengalaman yang sesuai dengan preferensi mereka. Masuk Instan Ada beberapa keyframe yang tidak bisa kami hapus begitu saja, seperti animasi masuk. Nilainya harus berubah, harus bernyawa; jika tidak, elemen tersebut tidak akan memiliki nilai yang benar. Namun dalam gerakan tereduksi, transisi dari nilai awal ini harus terjadi secara instan. Untuk mencapai hal ini, kami akan menentukan kumpulan bingkai utama tambahan yang nilainya langsung melonjak ke status akhir. Ini menjadi keyframe default kami. Kemudian, kita akan menambahkan keyframe biasa di dalam kueri media untuk pengaturan gerakan yang dikurangi ke tanpa preferensi, seperti pada contoh sebelumnya. /* muncul seketika untuk mengurangi gerakan */ @keyframes kf-zoom { dari, ke { skala: var(--kf-zoom-to, 1); } }

@media (lebih memilih gerakan yang dikurangi: tidak ada preferensi) { /* Keyframe zoom asli */ @keyframes kf-zoom { dari { skala: var(--kf-zoom-from, 0.8); } ke { skala: var(--kf-zoom-to, 1); } } }

Dengan cara ini, pengguna yang lebih menyukai gerakan yang dikurangi akan melihat elemen tersebut langsung muncul dalam keadaan akhirnya, sementara orang lain mendapatkan transisi animasi. Pendekatan Lembut Ada kalanya kami ingin mempertahankan beberapa gerakan, namun jauh lebih lembut dan tenang dibandingkan animasi aslinya. Misalnya, kita dapat mengganti pintu masuk pantulan dengan fade-in yang lembut.

@keyframes kf-bounce { /* Fade-in lembut untuk mengurangi gerakan */ }

@media (lebih memilih gerakan yang dikurangi: tidak ada preferensi) { @keyframes kf-bounce { /* Bingkai utama pentalan asli */ } }

Kini, pengguna yang mengaktifkan gerakan tereduksi masih dapat merasakan tampilannya, namun tanpa gerakan intens seperti animasi pantulan atau elastis. Dengan adanya elemen-elemen tersebut, pertanyaan berikutnya adalah bagaimana menjadikannya bagian dari alur kerja yang sebenarnya. Menulis keyframe yang fleksibel adalah satu hal, namun membuatnya dapat diandalkan di seluruh proyek besar memerlukan beberapa strategi yang harus saya pelajari dengan susah payah. Strategi Implementasi & Praktik Terbaik Setelah kami memiliki perpustakaan token keyframe yang solid, tantangan sebenarnya adalah bagaimana menerapkannya dalam pekerjaan sehari-hari.

Godaannya adalah untuk menghilangkan semua keyframe sekaligus dan menyatakan bahwa masalah telah terselesaikan, namun dalam praktiknya saya menemukan bahwa hasil terbaik datang dari penerapan secara bertahap. Mulailah dengan animasi yang paling umum, seperti fade atau slide. Ini adalah kemenangan mudah yang menunjukkan nilai langsung tanpa memerlukan penulisan ulang yang besar. Penamaan adalah hal lain yang patut mendapat perhatian. Awalan atau namespace yang konsisten memperjelas animasi mana yang merupakan token dan mana yang merupakan animasi lokal. Ini juga mencegah tabrakan yang tidak disengaja dan membantu anggota tim baru mengenali sistem bersama secara sekilas. Dokumentasi sama pentingnya dengan kode itu sendiri. Bahkan komentar singkat di atas setiap token keyframe dapat menghemat waktu berjam-jam untuk menebak-nebak nantinya. Pengembang harus dapat membuka file token, memindai efek yang mereka perlukan, dan menyalin pola penggunaan langsung ke komponennya. Fleksibilitas inilah yang menjadikan pendekatan ini sepadan dengan usaha yang dilakukan. Dengan menampilkan properti khusus yang masuk akal, kami memberikan ruang bagi tim untuk mengadaptasi animasi tanpa merusak sistem. Pada saat yang sama, cobalah untuk tidak memperumitnya. Sediakan tombol-tombol yang penting dan pertahankan pendapat lainnya. Terakhir, ingat aksesibilitas. Tidak semua animasi memerlukan alternatif gerakan yang dikurangi, tetapi banyak yang memerlukannya. Melakukan penyesuaian ini lebih awal berarti kami tidak perlu melakukan retrofit lagi nanti, dan ini menunjukkan tingkat kepedulian yang akan diperhatikan oleh pengguna kami meskipun mereka tidak pernah menyebutkannya.

Menurut pengalaman saya, memperlakukan token keyframe sebagai bagian dari alur kerja token desain kami adalah hal yang membuatnya melekat. Begitu diterapkan, efek tersebut tidak lagi terasa seperti efek khusus dan menjadi bagian dari bahasa desain, perpanjangan alami dari cara produk bergerak dan merespons. Menyelesaikan Animasi dapat menjadi salah satu bagian yang paling menyenangkan dalam membangun antarmuka, namun tanpa struktur, animasi juga dapat menjadi salah satu sumber frustrasi terbesar. Dengan memperlakukan keyframe sebagai token, Anda mengambil sesuatu yang biasanya berantakan dan sulit dikelola dan mengubahnya menjadi sistem yang jelas dan dapat diprediksi. Nilai sebenarnya bukan hanya menyimpan beberapa baris kode. Anda yakin bahwa saat Anda menggunakan fade, slide, zoom, atau spin, Anda tahu persis bagaimana perilakunya di seluruh proyek. Fleksibilitas yang berasal dari properti khusus tanpa kekacauan variasi yang tak ada habisnya. Dan itu terletak pada aksesibilitas yang dibangun menjadi fondasi, bukan ditambahkan sebagaisebuah renungan. Saya telah melihat ide-ide ini bekerja di tim yang berbeda dan basis kode yang berbeda, dan polanya selalu sama. Setelah token dipasang, bingkai utama tidak lagi menjadi kumpulan trik yang tersebar dan menjadi bagian dari bahasa desain. Mereka membuat produk terasa lebih disengaja, lebih konsisten, dan lebih hidup. Jika Anda mengambil satu hal dari artikel ini, biarlah ini: animasi berhak mendapatkan perhatian dan struktur yang sama seperti yang kita berikan pada warna, tipografi, dan spasi. Investasi kecil pada token keyframe akan terbayar setiap kali antarmuka Anda berpindah.

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