Efek slide carousel adalah cara yang bagus untuk menambahkan daya tarik visual ke carousel. Saat pengguna men-scroll slide, setiap slide dapat dianimasikan saat masuk, berada di tengah, dan keluar dari scrollport. Misalnya, slide dapat memudar, berputar, atau berubah ukurannya. Hal ini menciptakan pengalaman pengguna yang dinamis dan menarik. Tidak seperti animasi masuk/keluar yang sederhana, efek ini menggunakan satu animasi berkelanjutan untuk mengontrol tampilan slide di seluruh scrollport.
Cara menerapkan
Berikut cara membuat efek slide carousel:
Buat scroller: Elemen ini akan berfungsi sebagai penampung untuk slide carousel Anda. Dalam contoh ini,
overflow-x: scrolldigunakan untuk memungkinkan scroll horizontal.<ul class="scroller"> <li class="entry">1</li> <li class="entry">2</li> <li class="entry">3</li> … </ul>.scroller { overflow-x: scroll; }Tentukan animasi: Buat animasi CSS yang menentukan berbagai status slide saat melintasi scrollport. Anda dapat menentukan keyframe untuk bagian animasi mana pun. Misalnya, Anda dapat menentukan status saat slide berada di tengah area scroll dengan menyertakan keyframe
50%. Dalam contoh ini, propertiscalemembuat slide membesar saat mendekati bagian tengah dan mengecil saat menjauh.@keyframes animate { 0% { scale: 0.5; } 50% { scale: 1; } 100% { scale: 0.5; } }Terapkan animasi dan
view-timeline: Lampirkan animasi ke slide carousel dan tautkan keview-timelineyang melacak elemen saat di-scroll di container..scroller > * { animation: animate auto linear both; animation-timeline: view(inline); }Secara default,
view()melacak elemen pada sumbublock. Jika perlu melacaknya pada sumbuinline, Anda dapat menggunakanview(inline).
Kode contoh
Kode ini menganimasikan item carousel dari scroller horizontal saat di-scroll menggunakan view-timeline anonim:
@keyframes animate {
0% {
scale: 0.5;
}
50% {
scale: 1;
}
100% {
scale: 0.5;
}
}
.scroller > * {
/* Applies the animation using an `auto` duration */
animation: animate auto linear both;
/* Sets the animation timeline to use an anonymous view progress timeline, tracking the element's progress through the scroller on the inline axis */
animation-timeline: view(inline);
}
Kode ini menganimasikan item carousel dari scroller horizontal saat di-scroll menggunakan view-timeline bernama:
@keyframes animate {
0% {
scale: 0.5;
}
50% {
scale: 1;
}
100% {
scale: 0.5;
}
}
/* This creates a named view-timeline on each carousel item. The timeline is used to drive the animation that is applied on the same element. */
.scroller > * {
/* Applies the animation using an `auto` duration */
animation: animate auto linear both;
/* Defines a named view progress timeline, tracking the element's progress through the scroller on the inline axis */
view-timeline: --item inline;
/* Sets the animation timeline to use the named view progress timeline defined above */
animation-timeline: --item;
}
Praktik Terbaik
Saat menggunakan animasi berbasis scroll, penting untuk mengikuti beberapa praktik terbaik guna memastikan pengalaman yang lancar dan mudah diakses:
- LAKUKAN penyertaan deteksi fitur: Tidak semua browser mendukung animasi berbasis scroll. Gunakan
@supports ((animation-timeline: view()) and (animation-range: entry))untuk memeriksa dukungan dan memberikan penggantian untuk browser yang tidak mendukungnya.- Pemeriksaan
(animation-range: entry)HARUS disertakan di sini, untuk memfilter browser yang hanya memiliki dukungan parsial. - JANGAN gunakan paket
scroll-timeline-polyfilluntuk strategi penggantian karena fiturnya tidak lengkap dan memiliki banyak masalah umum. - Jika animasi hanya dianggap sebagai dekoratif, pilih Progressive Enhancement dan JANGAN berikan penggantian.
- Pemeriksaan
- LAKUKAN penghormatan terhadap preferensi pengguna: Beberapa pengguna lebih memilih untuk memiliki lebih sedikit gerakan di web. Gunakan kueri media
prefers-reduced-motionuntuk menonaktifkan atau mengurangi animasi bagi pengguna ini. - LAKUKAN upaya untuk menganimasikan hanya properti CSS yang berperforma tinggi: Untuk animasi yang paling lancar, tetap gunakan properti animasi yang dapat ditangani oleh thread compositor browser, seperti
transformdanopacity. Menganimasikan properti lain sepertiwidthatauheightdapat menyebabkan masalah performa. - LAKUKAN penggunaan urutan deklarasi yang benar: Saat menggunakan properti singkat
animation, deklarasikananimation-timelinedananimation-rangesetelahnya untuk mencegah properti singkat mereset linimasa.
Pilih view-timeline bernama jika beberapa elemen DOM perlu dianimasikan berdasarkan linimasa yang sama, atau jika Anda perlu menganimasikan turunan elemen yang memiliki view-timeline yang ditentukan di dalamnya. Jika elemen yang Anda animasikan juga merupakan elemen yang menentukan view-timeline, Anda dapat menggunakan view-timeline anonim menggunakan view().
Saat menggunakan fungsi view() untuk membuat animasi berbasis scroll:
- OPSIONAL jelaskan sumbu yang akan dilacak: Jika tidak menargetkan sumbu
blockdefault (seperti dalam scroller horizontal), jelaskan sumbu yang akan dilacak denganview(block)atauview(inline).
Saat menggunakan properti view-timeline untuk membuat animasi berbasis scroll:
- GUNAKAN
<dashed-ident>CSS untuk nama (misalnya,view-timeline: --my-custom-name) - OPSIONAL tentukan sumbu yang akan dilacak: Jika tidak menargetkan sumbu
blockdefault (seperti dalam scroller horizontal), tentukan sumbu yang akan dilacak denganview-timeline-axis. - LAKUKAN: pastikan cakupan pencarian berfungsi: Jika elemen yang mendeklarasikan
view-timelinebukan ancestor hierarki datar dari elemen animasi, naikkan visibilitas namaview-timelinemenggunakantimeline-scopepada ancestor bersama.
Dukungan browser dan strategi penggantian
Oleh karena itu, strategi penggantian biasanya diperlukan.
Untuk browser yang tidak mendukung animasi berbasis scroll, Anda dapat menggunakan penggantian untuk membuat ulang efek visual. Penggantian biasanya dibuat dengan pemroses scroll (untuk efek ScrollTimeline) atau IntersectionObserver API (untuk efek ViewTimeline).
Di browser dengan dukungan bawaan untuk animasi berbasis scroll, SELALU gunakan implementasi CSS native karena lebih berperforma.
Perhatikan bahwa tidak semua efek dapat dibuat ulang menggunakan pendekatan penggantian.
Khusus untuk kasus penggunaan ini, skrip berikut menerapkan penggantian untuk browser yang tidak mendukung animasi berbasis scroll. API ini menggunakan Web Animations API (Element.animate()) untuk membuat animasi yang dijeda untuk setiap item dalam carousel. Kemudian, kode ini memproses peristiwa scroll pada scroller dan memperbarui currentTime setiap animasi berdasarkan progres scroll item dalam scroller.
// Fallback for browsers that don't support scroll-driven animations
if (!CSS.supports('(animation-timeline: view()) and (animation-range: entry)')) {
const scroller = document.querySelector('.scroller');
const entries = document.querySelectorAll('.entry');
// Create a map to store animations
const animations = new Map();
entries.forEach(entry => {
const animation = entry.animate(
{
scale: ['0.5', '1', '0.5']
},
{
duration: 1, // We'll control the time ourselves
fill: 'both'
}
);
animation.pause();
animations.set(entry, animation);
});
// Update animations on scroll
const tick = () => {
const scrollerRect = scroller.getBoundingClientRect();
entries.forEach(entry => {
const animation = animations.get(entry);
if (!animation) return;
const entryRect = entry.getBoundingClientRect();
const progress = (entryRect.left + entryRect.width / 2 - scrollerRect.left) / scrollerRect.width;
animation.currentTime = progress;
});
};
scroller.addEventListener('scroll', tick);
tick();
}