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

Kullanıcınızı bir etkileşimden diğerine yönlendiren hareket, tüm dijital deneyimlerin temel parçasıdır. Bununla birlikte, web platformundaki akıcı animasyonlar konusunda bazı eksiklikler vardır. Bunlar, giriş ve çıkış animasyonlarını kolayca canlandırma ve iletişim kutuları ve pop-over'lar gibi kapatılabilir öğeler için üst katmana sorunsuz bir şekilde animasyon uygulama imkanını içerir.

Chrome 116 ve 117, bu boşlukları doldurmak için dört yeni web platformu özelliği içerir. Bu özellikler, ayrık mülkler için yumuşak animasyonlar ve geçişler sağlar.

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

  • Bir animasyon karesi zaman çizelgesinde display ve content-visibility animasyonlarını ekleyebilme (Chrome 116'dan).
  • display gibi ayrı özelliklerin geçişlerini etkinleştirmek için allow-discrete anahtar kelimesini içeren transition-behavior özelliği (Chrome 117'den).
  • display: none öğesinden üst katmana giriş efektlerini canlandırmak için @starting-style kuralı (Chrome 117'den).
  • Animasyon sırasında üst katman davranışını kontrol etmek için overlay özelliği (Chrome 117'den). ## Animasyon karelerinde animasyonları gösterme

Chrome 116'dan itibaren animasyon karesi kurallarında display ve content-visibility kullanabilirsiniz. Daha sonra, animasyon karesi oluştuğu anda bu öğeler değişir. Bu özelliğin desteklenmesi için yeni değerlere gerek yoktur:

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

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

Yukarıdaki örnekte, 0,5 sn.süre boyunca opaklık 0 olarak gösterilir, ardından görüntü yok olarak ayarlanır. Buna ek olarak, forwards anahtar kelimesi, animasyonun bitiş durumunda kalmasını sağlar. Böylece, uygulandığı öğe display: none ve opacity: 0 kalır.

Bu, bir geçişle neler yapabileceğinizi 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 ilk olarak y ekseninde döner, bir ton rotasyonundan geçer ve ardından zaman çizelgesi boyunca 80% konumunda opaklığını 1'den 0'a geçirir. Son olarak, display: block olan kart display: none olarak değiştirilir.

Bu çıkış animasyonlarını doğrudan bir öğeye uygulamak yerine animasyonlar için tetikleyici ayarlayabilirsiniz. Örneğin, animasyonun uygulanması için sınıfı tetikleyen bir düğmeye aşağıdaki gibi bir etkinlik işleyici ekleyerek:

.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 gösterilmektedir. Bunu daha da ileri götürmek ve animasyonun önce bitmesini sağlamak için zaman aşımıyla DOM düğümünü kaldırmak isteyebileceğiniz durumlar vardır.

Ayrık animasyonları geçirme

Animasyon kareleri ile ayrı ayrı mülklerin animasyonunun aksine, ayrı mülklerin geçişini yapmak için allow-discrete geçiş davranışı modunu kullanmanız gerekir.

transition-behavior mülkü

allow-discrete modu, ayrı geçişleri mümkün kılan bir özelliktir 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österir ancak görsel olarak benzer görünür.

transition kısaltması bu değeri de belirler. 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 ayrık özelliğe animasyon ekleyecekseniz 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 kullanın. Bu, "açılmadan önce" durumudur (animasyon yaptığınız yerdir).

/*  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 şu YAPILACAKLAR listesi öğeleri için hem giriş hem de çıkış durumunuz var:

Üst katmana doğru ve üst katmandan çıkmak için öğelerin animasyonunu oluşturma

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

Diyaloğun basit bir örneği şöyle 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;
}

Bir sonraki örnekte, giriş ve çıkış efektleri farklıdır. Görüntü alanının alt kısmından yukarıya animasyon ekleyerek girin, efektten çıkıp görüntü alanının üst kısmına gidin. Ayrıca, daha fazla görsel kapsülleme için iç içe yerleştirilmiş CSS ile yazılır.

Bir pop-up'ı canlandırırken 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 öğesini karartmak için geçiş listenize overlay özelliğini ekleyin. popover ve dialog, üst öğe klipleri ile dönüştürme işlemlerini gerçekleştirir ve ayrıca içeriği üst katmana yerleştirir. overlay öğesinin geçişini yapmazsanız öğeniz hemen kırpılır, dönüştürülür ve örtülür. Ayrıca geçiş gerçekleşmez.

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

Bunun yerine, overlay özelliğini diğer özelliklerle birlikte canlandırmak için geçişe veya animasyona overlay ekleyin ve animasyon sırasında üst katmanda kalmasını sağlayın. Bu işlem ç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çıksa bindirme, üst katmanın içine ve dışına yumuşak geçişi kontrol etmenize yardımcı olur. Aradaki farkı bu basit örnekte görebilirsiniz. Pencerenin geçişini yaparken ikinci pop-up'a overlay uygulamazsanız, geçiş başlamadan önce ilk olarak üst katmanın dışına çıkar ve diğer pop-up'ın arkasına atlar. Bu çok akıcı bir efekt değildir.

Görüntüleme geçişleriyle ilgili not

DOM'ye öğe ekleyip çıkarmak gibi DOM değişiklikleri yapıyorsanız sorunsuz animasyonlar için bir diğer harika çözüm de görüntüleme geçişleridir. Burada, görünüm geçişleri kullanılarak oluşturulan yukarıdaki örneklerden ikisini görebilirsiniz.

Bu ilk demoda, @starting-style ve diğer CSS dönüştürmelerini ayarlamak yerine görünüm geçişlerini yönetebilirsiniz. Görüntüleme geçişi aşağıdaki gibi ayarlanır:

Öncelikle, CSS'de her karta bağımsız 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 (bu örnekte kartı kaldırarak) bir görünüm geçişine sarmalayı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ı, solma ve şekil değiştirme işlemlerini her bir kartın yeni konumuna getirebiliyor.

Bu özelliğin kullanışlı olabileceği bir başka ö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: