Transisi Elemen Grup

Saat item ditambahkan atau dihapus dari daftar, atau diatur ulang, transisi dapat membantu pengguna mempertahankan konteks. Transisi tampilan menyediakan cara untuk melakukan transisi antara dua status elemen dengan memberikan view-transition-name unik pada elemen. Jika beberapa elemen di halaman memiliki perilaku transisi yang sama, view-transition-class memungkinkan Anda menentukan logika tersebut sekali di CSS, bukan mengulanginya untuk setiap view-transition-name yang unik. Hal ini membuat stylesheet Anda tetap dapat dikelola sekaligus memastikan animasi yang konsisten di seluruh grup elemen.

Langkah-langkah implementasi

  1. Menetapkan nama unik dan kelas bersama

    Setiap elemen yang perlu dilacak satu per satu selama transisi harus memiliki view-transition-name yang unik.

    <!-- Mandatory: Each element must have a unique view-transition-name -->
    <li style="view-transition-name: item-1" class="item">Item 1</li>
    <li style="view-transition-name: item-2" class="item">Item 2</li>
    

    Untuk menerapkan gaya bersama, tetapkan juga view-transition-class.

    .item {
      view-transition-class: list-item;
    }
    
  2. Menentukan logika transisi bersama

    Gunakan elemen semu ::view-transition-group() dengan pemilih class untuk menerapkan gaya ke semua anggota grup tersebut.

    /* Targets any view transition group that has the 'list-item' class */
    ::view-transition-group(.list-item) {
      animation-duration: 0.5s;
      animation-timing-function: ease-in-out;
    }
    
    /* Handle accessibility by respecting motion preferences */
    @media (prefers-reduced-motion: reduce) {
      /* Disable all group transitions, including the default `root` group. */
      ::view-transition-group(*),
      ::view-transition-old(*),
      ::view-transition-new(*) {
        animation: none !important;
      }
    }
    
  3. Opsional: Menentukan animasi masuk dan keluar

    Gunakan pemilih :only-child untuk menambahkan transisi tertentu ke elemen yang ditambahkan atau dihapus. Elemen semu ::view-transition-new() dan ::view-transition-old() adalah turunan dari elemen semu ::view-transition-image-pair(), sehingga kita dapat menentukan apakah elemen tersebut ditambahkan atau dihapus jika merupakan satu-satunya turunan.

    /* A `::view-transition-new()` element is the only child if it wasn't present before the view transition, so it is an added element. */
    ::view-transition-new(.list-item):only-child {
      animation-name: slide-in;
      /* Specify an animation duration if you want something different than the UA default of 0.5s */
      animation-duration: 1s;
    }
    /* A `::view-transition-old()` element is the only child if it isn't present after the view transition, so it is a removed element. */
    ::view-transition-old(.list-item):only-child {
      animation-name: slide-out;
      /* Specify an animation duration if you want something different than the UA default of 0.5s */
      animation-duration: 1s;
    }
    
    @keyframes slide-in {
      from {
        translate: -100vw 0;
      }
    }
    @keyframes slide-out {
      to {
        translate: -100vw 0;
      }
    }
    
  4. Memicu transisi

    Gabungkan update DOM di document.startViewTransition(). Browser akan menangkap status lama, melakukan update, lalu menganimasikan ke status baru.

    function updateList(newData) {
      document.startViewTransition(() => {
        // All DOM changes inside this callback will be transitioned
        render(newData);
      });
    }
    
  5. Mempertahankan interaktivitas elemen yang tidak ditransisikan

Transisi tampilan berfungsi dengan menempatkan snapshot elemen DOM, lalu mentransisikan snapshot tersebut. Artinya, selama transisi, elemen tidak bersifat interaktif. Jika ada elemen interaktif yang tidak ditransisikan, Anda dapat membuatnya interaktif dengan menonaktifkan peristiwa sentuh pada transisi tampilan.

::view-transition {
  /* Non-transitioned elements below the view transitions remain interactive */
  pointer-events: none;
}

Selain itu, secara default, elemen :root memiliki transisi tampilan bernama root, yang memungkinkan transisi halaman penuh default. Jika tidak ada perubahan pada elemen root, transisi ini akan terjadi di antara dua snapshot yang identik, yang tidak interaktif. Karena kita hanya mentransisikan elemen tertentu, bukan seluruh layar, kita dapat menonaktifkan transisi root.

:root {
  /* Disable the root transition because we are only transitioning specific elements. */
  view-transition-name: none;
}

Strategi penggantian

Transisi Tampilan adalah peningkatan progresif. Jika browser tidak mendukung document.startViewTransition, update DOM akan tetap terjadi secara langsung, sehingga memberikan pengalaman yang fungsional, tetapi tidak beranimasi.

if (document.startViewTransition) {
  document.startViewTransition(() => updateDOM());
} else {
  // Fallback: Perform the update without animation
  updateDOM();
}

Untuk CSS, browser yang tidak mengenali view-transition-class atau pemilih class ::view-transition-group() akan mengabaikan aturan tersebut, dan tidak ada animasi yang akan diterapkan.