Membuat animasi bertingkat

Animasi bertingkat memberikan efek menarik, yaitu beberapa elemen yang diurutkan akan dianimasikan secara berurutan dengan sedikit jeda di antara setiap elemen, bukan semuanya dianimasikan sekaligus. Teknik ini sering digunakan dalam daftar, galeri, atau menu navigasi untuk memandu mata pengguna dan menambahkan kesan yang rapi dan berirama pada interaksi.

Menyusun animasi dengan sibling-index()

Gunakan properti sibling-index() pada properti animation-delay sehingga animasi pada setiap elemen diimbangi dengan angka yang proporsional dengan posisinya di induknya. Fungsi sibling-index() menampilkan bilangan bulat, sehingga harus dikalikan dengan satuan waktu untuk mengonversinya menjadi waktu.

#stagger-list > .item {
  --stagger-time: 0.1s;
  /* Define the animation first */
  animation: fade-in 0.4s;
  /* Set the `animation-delay` to a time multiplied by the `sibling-index()` */
  animation-delay: calc(sibling-index() * var(--stagger-time))
}

WAJIB: Hormati preferensi pengguna dengan menonaktifkan animasi untuk pengguna yang lebih memilih gerakan yang dikurangi.

@media (prefers-reduced-motion: reduce){
  /* Disable animation for users who prefer reduced motion. */
  #stagger-list > .item {
    animation: none;
  }
}

Strategi penggantian

Uji dukungan untuk sibling-index() menggunakan CSS dengan @supports (animation-delay: calc(sibling-index() * 0.1s)){} atau JavaScript dengan !CSS.supports('animation-delay: calc(sibling-index() * 0.1s)').

Untuk mendukung animasi bertahap di browser lama, gunakan JavaScript untuk menambahkan properti kustom --sibling-index ke setiap elemen seinduk. WAJIB: gabungkan ini dalam pengujian CSS.supports('animation-delay: calc(sibling-index() * 0.1s)') untuk menghindari menjalankan JavaScript yang tidak diperlukan.

if(!CSS.supports('animation-delay: calc(sibling-index() * 0.1s)')){
  const staggerList = document.getElementById('stagger-list');
  [...staggerList.children].forEach((el, index)=>el.style.setProperty('--sibling-index', index + 1));
}

Tambahkan deklarasi animation-delay yang menggunakan properti kustom --sibling-index. Deklarasi ini harus berada sebelum deklarasi animation-delay yang menggunakan fungsi sibling-index(). Ini tidak perlu digabungkan dalam @supports - browser lama tidak akan mengurai deklarasi kedua dan akan menggunakan deklarasi pertama.

#stagger-list > .item {
  animation-delay: calc(var(--sibling-index) * var(--stagger-time));
  animation-delay: calc(sibling-index() * var(--stagger-time));
}