Kaydırırken küçülen başlık

Kaydırıldığında küçülen başlık, sayfanın üst kısmındaki sabit bir başlık öğesinin, kullanıcı aşağı kaydırdıkça sorunsuz bir şekilde daha küçük bir boyuta geçtiği yaygın bir kullanıcı arayüzü kalıbıdır. Bu efekt genellikle, önemli gezinme veya marka öğelerini erişilebilir tutarken ana içerik için ekran alanını en üst düzeye çıkarmak amacıyla kullanılır. CSS kaydırmaya dayalı animasyonlar sayesinde bu efekt, bir animasyonu dokümanın kaydırma konumuna bağlayarak açıklayıcı ve performanslı bir şekilde elde edilebilir.

Nasıl uygulanır?

Kaydırıldığında küçülen bir başlık oluşturmak için aşağıdaki adımları uygulayın:

  1. Sabit bir başlık oluşturun: Sayfanın üst kısmına sabitlenmiş ve önceden tanımlanmış bir yüksekliğe sahip bir başlık öğesiyle başlayın.

    <header>HEADER</header>
    
    header {
      position: fixed;
      height: 200px;
      top: 0;
      left: 0;
      right: 0;
    }
    
  2. Küçültme animasyonunu tanımlayın: Başlığın yüksekliğini değiştiren bir CSS animasyonu oluşturun.

    @keyframes shrink {
      to {
        height: 50px;
      }
    }
    
  3. Animasyonu uygulama ve zaman çizelgesini kaydırma: Animasyonu başlığa ekleyin ve dokümanın kaydırma konumuna bağlamak için scroll() işlevini kullanın.

    header {
      animation: shrink auto linear both;
      animation-timeline: scroll(block root);
    }
    
  4. animation-range değerini ayarlayın: Animasyonun gerçekleşeceği kaydırma mesafesini belirtmek için animation-range özelliğini kullanın. Örneğin, kaydırma işleminin ilk 150 pikselinde başlığı küçültmek için animation-range: 0px 150px; kullanırsınız.

    header {
      animation-range: 0px 150px;
    }
    

İpucu: Başlıktan sonraki içeriğin başlık tarafından gizlenmesini önlemek için body öğesine (veya ana içerik kapsayıcısına) başlığın ilk yüksekliğine eşit bir padding-top ekleyin.

İpucu: Sayfa içeriğinin küçülen başlıkla senkronize şekilde kaydırılmasını sağlamak için animation-range-end değerini başlangıç ve bitiş boyutları arasındaki farka ayarlayın. Bu sayede animasyon, başlık nihai boyutuna ulaştığında tam olarak tamamlanır. Bu demoda başlık 200px değerinden 50px değerine küçülür. Bu nedenle animation-range-end, 150px olarak ayarlanır.

Örnek kod

@keyframes shrink {
  to {
    height: 50px;
  }
}

header {
  animation: shrink auto linear both;
  animation-timeline: scroll(block root);
  animation-range: 0px 150px;
}

En İyi Uygulamalar

Kaydırmaya dayalı animasyonları kullanırken sorunsuz ve erişilebilir bir deneyim sunmak için birkaç en iyi uygulamayı takip etmek önemlidir:

  • ÖZELLİK algılamayı ekleyin: Tüm tarayıcılar kaydırmaya dayalı animasyonları desteklemez. Destek durumunu kontrol etmek ve desteklemeyen tarayıcılar için yedek sağlamak üzere @supports ((animation-timeline: scroll()) and (animation-range: 0% 100%)) kullanın.
    • Yalnızca kısmi desteği olan tarayıcıları filtrelemek için (animation-range: 0% 100%) kontrolü buraya DAHİL EDİLMELİDİR.
    • Yedek strateji için scroll-timeline-polyfill paketini KULLANMAYIN. Bu paketin özellikleri tamamlanmamıştır ve bilinen birçok sorunu vardır.
    • Animasyonun yalnızca dekoratif olduğu düşünülüyorsa progresif geliştirmeyi tercih edin ve yedek SAĞLAMAYIN.
  • DO respect user preferences: Some users prefer to have less motion on the web. Bu kullanıcılar için animasyonlarınızı devre dışı bırakmak veya azaltmak üzere prefers-reduced-motion medya sorgusunu kullanın.
  • Yalnızca performanslı CSS özelliklerini canlandırmaya ÇALIŞIN: En akıcı animasyonlar için tarayıcının birleştirici iş parçacığı tarafından işlenebilen özellikleri (ör. transform ve opacity) canlandırın. width veya height gibi diğer özellikleri canlandırmak performans sorunlarına yol açabilir.
  • DO Doğru bildirim sırasını kullanın: animation kısayol özelliğini kullanırken, kısayolun zaman çizelgesini sıfırlamasını önlemek için animation-timeline ve animation-range özelliklerini sonra bildirin.

Kaydırmaya dayalı animasyon oluşturmak için scroll() işlevini kullanırken:

  • İSTEĞE BAĞLI Kaydırıcıyı açıkça belirtin: En yakın üst öğe kaydırıcıyı hedeflemiyorsanız scroll(root) veya scroll(self) ile hangi kaydırıcıyı kullanmak istediğinizi açıkça belirtin.
    • root, nearest veya self yeterli olmadığında adlandırılmış bir kaydırma zaman çizelgesi kullanın.
  • İSTEĞE BAĞLI İzlenecek eksen konusunda net olun: Varsayılan block eksenini hedeflemediğinizde (ör. yatay kaydırıcıda), scroll(block) veya scroll(inline) ile hangi eksenin izleneceği konusunda net olun.

Bu kullanım alanına özel olarak:

  • animation-range içinde yüzdeler kullanılırken animasyon uyguladığınız öğe position: static veya position: relative OLMAMALIDIR.
    • Bunun nedeni, bu öğelerin "akış içinde" kabul edilmesidir. Sayfayı kaydırdığınızda bu öğelerin küçülmesi, toplam kaydırma mesafesini azaltır ve bu nedenle, kaydırma sırasında hesaplanan 10% değerini etkiler.

Tarayıcı desteği ve yedek stratejiler

Bu nedenle, genellikle bir yedek strateji gerekir.

Kaydırmaya dayalı animasyonları desteklemeyen tarayıcılarda görsel efektleri yeniden oluşturmak için yedek kullanabilirsiniz. Yedekler genellikle bir kaydırma dinleyicisi (ScrollTimeline efektleri için) veya IntersectionObserver API (ViewTimeline efektleri için) ile oluşturulur.

Kaydırmaya dayalı animasyonlar için yerleşik desteğe sahip tarayıcılarda DAİMA yerel CSS uygulamasını kullanın. Bu uygulamalar daha yüksek performans sağlar.

Yedek yaklaşımı kullanılarak her efektin yeniden oluşturulamayacağını unutmayın.

Özellikle bu kullanım alanında, aşağıdaki komut dosyası, kaydırmaya dayalı animasyonları desteklemeyen tarayıcılar için yedek seçeneği uygular. Belgenin kaydırma konumunu 150px mesafede izlemek için kaydırma dinleyicisi kullanır ve başlığın yüksekliğini buna göre günceller.

// Fallback for browsers that don't support scroll-driven animations
if (!CSS.supports('(animation-timeline: scroll()) and (animation-range: 0% 100%)')) {
  const header = document.querySelector('header');

  const initialHeight = 200;
  const finalHeight = 50;
  const scrollDistance = 150;

  window.addEventListener('scroll', () => {
    const scrollY = window.scrollY;
    const scrollPercent = Math.min(1, scrollY / scrollDistance);
    const newHeight = initialHeight - (initialHeight - finalHeight) * scrollPercent;

    header.style.height = `${newHeight}px`;
  });
}