Sorunsuz giriş ve çıkış animasyonları için dört yeni CSS özelliği

Una Kravets
Una Kravets
Joey Arhar
Joey Arhar

Kullanıcınızı bir etkileşimden diğerine yönlendiren hareket, her dijital deneyimin temel bir parçasıdır. Ancak web platformundaki akıcı animasyonlarda birkaç eksik vardır. Bu özellikler arasında, giriş ve çıkış animasyonlarını kolayca canlandırmanın yanı sıra iletişim kutuları ve pop-up'lar gibi kapatılabilir öğeler için üst katmana geçişte sorunsuz olarak animasyon uygulanması yer alır.

Chrome 116 ve 117, bu boşlukları doldurmak için, ayrı mülkler için düzgün animasyonlar ve geçişler sağlayan dört yeni web platformu özelliği içeriyor.

Bu dört yeni özellik şunlardır:

  • Bir animasyon karesi zaman çizelgesinde display ve content-visibility animasyonları yapabilme (Chrome 116'dan itibaren).
  • display gibi ayrı mülklerin geçişlerini etkinleştirmek için allow-discrete anahtar kelimesini içeren transition-behavior özelliği (Chrome 117'den itibaren).
  • display: none uygulamasından üst katmana (Chrome 117'den) giriş efektlerini animasyon eklemek için @starting-style kuralı.
  • Animasyon sırasında üst katman davranışını kontrol etmek için kullanılan overlay özelliği (Chrome 117'den). ## Animasyon karelerinde animasyon görüntüleme

Chrome 116'da animasyon karesi kurallarında display ve content-visibility kullanabilirsiniz. Ardından, animasyon karesi oluştuğunda bunlar değişir. Bunu desteklemek için ek yeni değerler gerekmiyor:

.card {
  animation: fade-out 0.5s forwards;
}

@keyframes fade-out {
  100% {
    opacity: 0;
    display: none;
  }
}

Yukarıdaki örnekte opaklığa 0,5 sn.boyunca 0 olarak animasyon uygulanır ve daha sonra görüntüleme yok değerine ayarlanır. Buna ek olarak, forwards anahtar kelimesi, animasyonun bitiş durumunda kalmasını ve böylece uygulandığı öğenin display: none ve opacity: 0 kalmasını sağlar.

Bu, bir geçişle yapabileceklerinizi taklit eden basit bir örnektir (geçiş bölümündeki demoya bakın). Ancak geçişler aşağıdaki örnek gibi daha karmaşık animasyonlar oluşturamaz:

.card {
  animation: spin-and-delete 1s ease-in forwards;
}

@keyframes spin-and-delete {
  0% {
    transform: rotateY(0);
    filter: hue-rotate(0);
  }
  80% {
    transform: rotateY(360deg);
    filter: hue-rotate(180deg);
    opacity: 1;
  }
  100% {
    opacity: 0;
    display: none;
  }
}

spin-and-delete animasyonu, bir çıkış animasyonudur. Kart önce y ekseninde döner, bir ton rotasyonundan geçer ve ardından zaman çizelgesi boyunca 80% sırasında opaklığını 1'den 0'a geçirir. Son olarak kart, display: block yerine display: none olur.

Bu çıkış animasyonlarında, bunları doğrudan bir öğeye uygulamak yerine animasyonlar için bir tetikleyici ayarlayabilirsiniz. Örneğin, bir sınıfı animasyonu uygulamak üzere tetikleyen bir düğmeye aşağıdaki şekilde bir etkinlik işleyici ekleyebilirsiniz:

.spin-out {
   animation: spin-and-delete 1s ease-in forwards;
}
document.querySelector('.delete-btn').addEventListener('click', () => {
 document.querySelector('.card').classList.add('spin-out');
})

Yukarıdaki örnekte, artık display:none olan bir bitiş durumu mevcuttur. Birçok durumda bu işlemi bir adım ileri götürüp animasyonun önce bitmesini sağlamak için zaman aşımına sahip DOM düğümünü kaldırın.

Ayrı animasyonları geçirme

Animasyon kareleriyle ayrı özellikleri animasyon haline getirmenin aksine, ayrı özellikleri taşımak için allow-discrete geçiş davranışı modunu kullanmanız gerekir.

transition-behavior özelliği

allow-discrete modu, ayrı geçişleri mümkün kılar ve transition-behavior özelliğinin bir değeridir. transition-behavior, iki değeri kabul eder: normal ve allow-discrete.

.card {
  transition: opacity 0.25s, display 0.25s;
  transition-behavior: allow-discrete; /* Note: be sure to write this after the shorthand */
}

.card.fade-out {
  opacity: 0;
  display: none;
}
Not: Bu geçiş demosu, ilk animasyon demosundan farklı bir teknik gösterse de görsel olarak benzerdir.

transition kısayolu da bu değeri ayarlar. Böylece özelliği atlayabilir ve her geçiş için transition kısaltmasının sonunda allow-discrete anahtar kelimesini kullanabilirsiniz.

.card {
  transition: opacity 0.5s, display 0.5s allow-discrete;
}

.card.fade-out {
  opacity: 0;
  display: none;
}

Birden fazla münferit mülk canlandırıyorsanız canlandırmak istediğiniz her özellikten sonra allow-discrete eklemeniz gerekir. Örneğin:

.card {
  transition: opacity 0.5s, display 0.5s allow-discrete, overlay 0.5s allow-discrete;
}

.card.fade-out {
  opacity: 0;
  display: none;
}

Giriş animasyonları için @starting-style kuralı

Şu ana kadar bu makalede çıkış animasyonları ele alınmıştır. Giriş animasyonları oluşturmak için @starting-style kuralını kullanmanız gerekir.

Öğe sayfada açılmadan önce tarayıcının arayabileceği bir stil uygulamak için @starting-style politikasını kullanın. Bu, "açılmadan önceki" durumdur (animasyonu yaptığınız yer).

/*  0. BEFORE-OPEN STATE   */
/*  Starting point for the transition */
@starting-style {
  .item {
    opacity: 0;
    height: 0;
  }
}

/*  1. IS-OPEN STATE   */
/*  The state at which the element is open + transition logic */
.item {
  height: 3rem;
  display: grid;
  overflow: hidden;
  transition: opacity 0.5s, transform 0.5s, height 0.5s, display 0.5s allow-discrete;
}

/*  2. EXITING STATE   */
/*  While it is deleting, before DOM removal in JS, apply this
    transformation for height, opacity, and a transform which
    skews the element and moves it to the left before setting
    it to display: none */
.is-deleting {
  opacity: 0;
  height: 0;
  display: none;
  transform: skewX(50deg) translateX(-25vw);
}

Artık bu YAPILACAKLAR listesi öğeleri için hem giriş hem de çıkış durumunuz vardır:

Üst katmana giden ve katmandan ayrılan öğelere animasyon ekleme

Üst katmana ve üst katmandan öğelere animasyon eklemek için tarayıcıya nereden animasyonun yapılacağını belirtmek üzere "açık" durumda @starting-style belirtin. Bir iletişim kutusunda açık durum, [open] özelliğiyle tanımlanır. Pop-up için :popover-open sözde sınıfını kullanın.

Basit bir iletişim kutusu örneği şu şekilde olabilir:

/*   0. BEFORE-OPEN STATE   */
@starting-style {
  dialog[open] {
    translate: 0 100vh;
  }
}

/*   1. IS-OPEN STATE   */
dialog[open] {
  translate: 0 0;
}

/*   2. EXIT STATE   */
dialog {
  transition: translate 0.7s ease-out, overlay 0.7s ease-out allow-discrete, display 0.7s ease-out allow-discrete;
  translate: 0 100vh;
}

Sonraki örnekte, giriş ve çıkış efektleri farklıdır. Animasyonu görüntü alanının alt kısmından yukarıya doğru kaydırarak girin, efektten görüntü alanının üst kısmına geçin. Ayrıca, daha fazla görsel kapsülleme için iç içe yerleştirilmiş CSS ile yazılmıştır.

Pop-up animasyon yaparken daha önce kullanılan open özelliği yerine :popover-open sözde sınıfını kullanın.

.settings-popover {
  &:popover-open {
    /*  0. BEFORE-OPEN STATE  */
    /*  Initial state for what we're animating *in* from, 
        in this case: goes from lower (y + 20px) to center  */
    @starting-style {
      transform: translateY(20px);
      opacity: 0;
    }
    
    /*  1. IS-OPEN STATE  */
    /*  state when popover is open, BOTH:
        what we're transitioning *in* to 
        and transitioning *out* from */
    transform: translateY(0);
    opacity: 1;
  }
  
  /*  2. EXIT STATE  */
  /*  Initial state for what we're animating *out* to , 
      in this case: goes from center to (y - 50px) higher */
  transform: translateY(-50px);
  opacity: 0;
  
  /*  Enumerate transitioning properties, 
      including display and allow-discrete mode */
  transition: transform 0.5s, opacity 0.5s, display 0.5s allow-discrete;
}

overlay tesis

Son olarak, üst katmandaki bir popover veya dialog efektini karartmak için geçiş listenize overlay özelliğini ekleyin. popover ve dialog kaçış üst öğesi klipleri ve dönüşümlerinin yanı sıra içeriği en üst katmana da yerleştirir. overlay için geçiş yapmazsanız öğeniz hemen kırpılmaya, dönüştürülmeye ve örtülmeye devam eder. Geçişi görmezsiniz.

[open] {
  transition: opacity 1s, display 1s allow-discrete;
}

Bunun yerine, diğer özelliklerle birlikte overlay animasyonu için geçişe veya animasyona overlay ekleyin ve animasyon sırasında üst katmanda kaldığından emin olun. Bu çok daha düzgün görünür.

[open] {
  transition: opacity 1s, display 1s allow-discrete, overlay 1s allow-discrete;
}

Buna ek olarak, üst katmanda birden fazla öğe açık olduğunda, yer paylaşımı, üst katmanın içine ve dışına yumuşak geçişi kontrol etmenize yardımcı olur. Bu basit örnekte farkı görebilirsiniz. Geçişi gerçekleştirirken ikinci pop-up'a overlay eklemezseniz bu öğe geçişe başlamadan önce en üst katmanın dışına çıkar, diğer pop-up'ın arkasına atlanır. Bu çok sorunsuz bir efekt değildir.

Görünüm geçişleriyle ilgili bir not

DOM'ye öğe ekleme ve DOM'den öğe kaldırma gibi DOM değişiklikleri yapıyorsanız, işitsel animasyonlar için bir başka harika çözüm de görünüm geçişleridir. Görünüm geçişleri kullanılarak oluşturulan yukarıdaki örneklerden ikisi aşağıda verilmiştir.

Bu ilk demoda, geçişi @starting-style ve diğer CSS dönüşümlerini ayarlamak yerine görünüm geçişleri gerçekleştirecektir. Görünüm geçişi şu şekilde ayarlanır:

İlk olarak, CSS'de her karta ayrı bir view-transition-name verin.

.card-1 {
  view-transition-name: card-1;
}

.card-2 {
  view-transition-name: card-2;
}

/* etc. */

Ardından, JavaScript'te DOM mutasyonunu bir görünüm geçişinde sarmalayın (bu örnekte kartı kaldırın).

deleteBtn.addEventListener('click', () => {
  // Check for browser support
  if (document.startViewTransition) {
    document.startViewTransition(() => {
      // DOM mutation
      card.remove();
    });
  } 
  // Alternative if no browser support
  else {
    card.remove();
  }
})

Artık tarayıcı, her kartın solma ve şeklini yeni konumuna geçirebilir.

Bunun kullanışlı olabileceği başka bir örnek de liste öğesi ekleme/kaldırma demosudur. Bu durumda, oluşturulan her kart için benzersiz bir view-transition-name eklemeyi unutmayın.

Sonuç

Bu yeni platform özellikleri, bizi web platformundaki sorunsuz giriş ve çıkış animasyonlarına bir adım daha yaklaştırıyor. Daha fazla bilgi edinmek için şu bağlantılara göz atın: