CSS Scroll Snap ile iyi kontrol edilmiş kaydırma

Kaydırma tutturma konumlarını belirterek iyi kontrol edilen kaydırma deneyimleri oluşturun.

CSS Scroll Snap özelliği, web geliştiricilerin kaydırma tutma konumlarını belirterek iyi kontrol edilen kaydırma deneyimleri oluşturmasına olanak tanır. Sayfalandırılmış makaleler ve resim bantları, bu duruma ilişkin yaygın olarak kullanılan iki örnektir. CSS Scroll Snap, bu popüler kullanıcı deneyimi kalıplarını oluşturmak için kullanımı kolay ve tutarlı bir API sağlar.

Arka plan

Kaydırma sabitlemenin avantajları

Kaydırma, web'deki içeriklerle etkileşim kurmanın popüler ve doğal bir yoludur. Bu özellik, ekranda aynı anda görünen bilgilerden daha fazlasına erişim sağlayan yerel bir platform aracıdır ve özellikle sınırlı ekran alanına sahip mobil platformlarda hayati önem taşır. Bu nedenle, web yazarlarının içerikleri derin hiyerarşiler yerine kaydırılabilir düz listeler halinde düzenlemeyi giderek daha fazla tercih etmesi şaşırtıcı değildir.

Kaydırmanın en büyük dezavantajı hassasiyetinin düşük olmasıdır. Kaydırma işlemi nadiren bir paragraf veya cümleyle hizalanır. Bu durum, kaydırma işlemi sayfanın veya resmin ortasında bittiğinde anlamlı sınırlara sahip sayfalandırılmış ya da öğelendirilmiş içeriklerde daha da belirgindir. Bu durumda içerik kısmen görünür durumda kalır. Bu kullanım alanları, iyi kontrol edilen bir kaydırma deneyiminden yararlanır.

Web geliştiriciler, bu eksikliği gidermek için uzun süredir kaydırmayı kontrol etmek üzere JavaScript tabanlı çözümlerden yararlanmaktadır. Ancak JavaScript tabanlı çözümler, kaydırma özelleştirme temel öğelerinin veya birleştirilmiş kaydırmaya erişimin olmaması nedeniyle tam doğrulukta bir çözüm sunamaz. CSS Scroll Snap, tarayıcılarda tutarlı bir şekilde çalışan hızlı, yüksek kaliteli ve kullanımı kolay bir çözüm sunar.

CSS Scroll Snap, web yazarlarının her kaydırma kapsayıcısını, kaydırma işlemlerinin tamamlanacağı sınırlar ile işaretlemesine olanak tanır. Tarayıcılar daha sonra kaydırma işleminin özelliklerine, kaydırma kapsayıcısının düzenine ve görünürlüğüne ve tutturma konumlarının ayrıntılarına bağlı olarak en uygun bitiş konumunu seçer ve bu konuma sorunsuz bir şekilde animasyon uygular. Önceki örneğimize dönecek olursak, kullanıcı bandı kaydırmayı bitirdiğinde görünür resim yerine oturur. JavaScript ile kaydırma ayarlaması yapılması gerekmez.

Resim bandı ile CSS kaydırma yakalama kullanma örneği.
Resim rulosuyla CSS kaydırma yakalama kullanımına ilişkin örnek. Burada kaydırma tutturma, kaydırma sonunda bir görüntünün yatay merkezinin kaydırma kapsayıcısının yatay merkeziyle hizalanmasını sağlar.

CSS Scroll Snap

Kaydırma sabitleme, kaydırma işlemi tamamlandıktan sonra kaydırma kapsayıcısının kaydırma uzaklığını tercih edilen bir sabitleme konumuna ayarlama işlemidir.

Kaydırma kapsayıcısı, scroll-snap-type özelliği kullanılarak kaydırma sabitleme özelliğini etkinleştirebilir. Bu, tarayıcıya bu kaydırma kapsayıcısını alt öğeleri tarafından oluşturulan tutturma konumlarına tutturmayı düşünmesi gerektiğini söyler. scroll-snap-type kaydırmanın gerçekleşeceği ekseni (x, y veya both) ve yakalama katılığını (mandatory, proximity) belirler. Bu konulara daha sonra değineceğiz.

Bir öğede istenen hizalama bildirilerek tutturma konumu oluşturulabilir. Bu konum, en yakın üst öğe kaydırma kapsayıcısının ve öğenin, verilen eksen için belirtildiği şekilde hizalandığı kaydırma uzaklığıdır. Her eksende şu hizalamalar mümkündür: start, end, center.

start hizalaması, kaydırma kapsayıcısının snapport başlangıç kenarının, öğe tutturma alanı başlangıç kenarıyla aynı hizada olması gerektiği anlamına gelir. Benzer şekilde, end ve center hizalamaları, kaydırma kapsayıcısının tutturma noktası bitiş kenarının veya merkezinin, öğe tutturma alanı bitiş kenarı veya merkeziyle aynı hizada olması gerektiği anlamına gelir.

Yatay kaydırma ekseninde çeşitli hizalamalara örnek.

Aşağıdaki örneklerde bu kavramların nasıl kullanılacağı gösterilmektedir.

Kaydırma sabitleme için yaygın bir kullanım alanı, resim galerisidir. Örneğin, kaydırdıkça her resme tutturulan yatay bir resim döngüsü oluşturmak için kaydırma kapsayıcının yatay eksende zorunlu bir scroll-snap-type'ye sahip olmasını belirtebiliriz. Tutturmanın resmi döngü içinde ortalamasını sağlamak için her resmi scroll-snap-align: center olarak ayarlayabiliriz.

#gallery {
  scroll-snap-type: x mandatory;
  overflow-x: scroll;
  display: flex;
}

#gallery img {
   scroll-snap-align: center;
}
<div id="gallery">
  <img src="cat.jpg">
  <img src="dog.jpg">
  <img src="another_cute_animal.jpg">
</div>

Tutma konumları bir öğeyle ilişkilendirildiğinden tutma algoritması, öğe ve kaydırma kapsayıcısının boyutu göz önüne alındığında ne zaman ve nasıl tutturacağı konusunda akıllıca davranabilir. Örneğin, bir resmin rulodan daha büyük olduğu durumu ele alalım. Basit bir tutturma algoritması, kullanıcının tam resmi görmek için kaydırma yapmasını engelleyebilir. Ancak spesifikasyon, uygulamaların bu durumu algılamasını ve kullanıcının yalnızca kenarlara tutturarak bu resimde serbestçe kaydırmasına izin vermesini gerektirir.

Örnek: yolculuk içeren bir ürün sayfası

Kaydırma sabitlemeden yararlanabilecek bir diğer yaygın durum da dikey olarak kaydırılacak birden fazla mantıksal bölüm içeren sayfalardır. Örneğin, tipik bir ürün sayfası. scroll-snap-type: y proximity;, bu gibi durumlar için daha uygun bir seçenektir. Kullanıcı belirli bir bölümün ortasına kaydırdığında müdahale etmez ancak yeterince yakına kaydırdığında yeni bir bölüme geçerek dikkatini oraya yönlendirir.

Bu işlemi şu şekilde yapabilirsiniz:

article {
  scroll-snap-type: y proximity;
  /* Reserve space for header plus some extra space for sneak peeking. */
  scroll-padding-top: 15vh;
  overflow-y: scroll;
}
section {
  /* Snap align start. */
  scroll-snap-align: start;
}
header {
  position: fixed;
  height: 10vh;
}
<article>
  <header> Header </header>
  <section> Section One </section>
  <section> Section Two </section>
  <section> Section Three </section>
</article>

Kaydırma dolgusu ve kenar boşluğu

Ürün sayfasında sabit konumlu bir üst başlık var. Tasarımda ayrıca, yukarıdaki içerikle ilgili kullanıcılara tasarım ipucu vermek için kaydırma kapsayıcısı yerine oturduğunda üst bölümün bir kısmının görünür kalması da isteniyordu.

scroll-padding özelliği, kaydırma kapsayıcısının veya kaydırma hizalama hesaplanırken kullanılan snapport'un etkili görünür bölgesini ayarlamak için kullanılabilecek yeni bir CSS özelliğidir. Özellik, kaydırma kapsayıcısının dolgu kutusuna göre bir iç boşluk tanımlar. Örneğimizde, kaydırma kapsayıcısının üst kenarının 15vh altına 15vh ek bir iç kısım ekleniyor. Bu, tarayıcıya kaydırma kapsayıcısının üst kenarının 15vh altına 15vh daha düşük bir konumu kaydırma için dikey başlangıç kenarı olarak kabul etmesini söylüyor. Yakalama sırasında, yakalama hedefi öğesinin başlangıç kenarı bu yeni konumla aynı hizaya gelir ve üstte boşluk bırakır.

scroll-margin özelliği, scroll-padding işlevinin kaydırma kapsayıcısında çalıştığına benzer şekilde, yapışma hedefi etkili kutusunu ayarlamak için kullanılan başlangıç miktarını tanımlar.

Bu iki özelliğin adında "snap" kelimesinin yer almadığını fark etmiş olabilirsiniz. Bu, kutuyu tüm ilgili kaydırma işlemleri için gerçekten değiştirdikleri ve yalnızca kaydırma işlemini sabitlemedikleri için kasıtlı olarak yapılmıştır. Örneğin, Chrome, PageDown ve PageUp gibi sayfalama kaydırma işlemleri için sayfa boyutunu hesaplarken ve Element.scrollIntoView() işlemi için kaydırma miktarını hesaplarken bunları dikkate alır.

Diğer kaydırma API'leriyle etkileşim

DOM Scrolling API

Kaydırma işlemleri, komut dosyası tarafından başlatılanlar da dahil olmak üzere sonra gerçekleşir. Element.scrollTo gibi API'leri kullandığınızda tarayıcı, işlemin amaçlanan kaydırma konumunu hesaplar ve ardından son sabitlenmiş konumu bulmak için uygun sabitleme mantığını uygular. Bu nedenle, kullanıcının tutturma için herhangi bir manuel hesaplama yapmasına gerek yoktur.

Kolay kaydırma

Sorunsuz kaydırma, programatik bir kaydırma işleminin davranışını kontrol ederken kaydırma tutturma, hedefi belirler. Kaydırmanın dik yönlerini kontrol ettikleri için birlikte kullanılabilir ve birbirini tamamlayabilirler.

Kaydırma sonu davranışı

Overscroll behavior API, kaydırmanın birden fazla öğe arasında nasıl zincirlendiğini kontrol eder ve kaydırma yakalama özelliğinden etkilenmez.

Uyarılar ve en iyi uygulamalar

Hedef öğeler arasında geniş boşluklar olduğunda zorunlu tutturma kullanmaktan kaçının. Bu durum, anlık görüntü konumları arasındaki içeriğe erişilememesine neden olabilir.

Çoğu durumda, özellik algılama yapmaya gerek kalmadan kaydırma kilitleme geliştirme olarak eklenebilir. Gerekirse CSS Scroll Snap desteğini algılamak için @supports veya CSS.supports kullanın. Kullanımdan kaldırılan spesifikasyonda da bulunan scroll-snap-type özelliğini kullanmaktan kaçının.

CSS'de özellik algılama

@supports (scroll-snap-align: start) {
  article {
    scroll-snap-type: y proximity;
    scroll-padding-top: 15vh;
    overflow-y: scroll;
  }
}

JavaScript'te özellik algılama

if (CSS.supports('scroll-snap-align: start')) {
  // use css scroll snap
} else {
  // use fallback
}

Element.scrollTo gibi programatik olarak kaydırma yapan API'lerin her zaman istenen kaydırma uzaklığında tamamlandığını varsaymayın. Kaydırma yakalama, programatik kaydırma tamamlandıktan sonra kaydırma uzaklığını ayarlayabilir. Kaydırma başka nedenlerle de kesintiye uğrayabileceğinden, bu varsayım kaydırma yakalama özelliğinden önce bile doğru değildi. Ancak bu durum, kaydırma yakalama özelliğiyle birlikte daha da belirginleşti.

Gelecekte yapılacak çalışmalar

Kaydırma deneyimi, Chrome ekibinin kısa süre önce yaptığı bir ankette odak noktasıydı. Anket sonuçları, eklenti kitaplıkları ile CSS arasındaki farkı azaltmak için ek çalışma yapılması gereken çeşitli alanları belirledi. Yaklaşan çalışmalar scroll-snap üzerine odaklanacak. Bu kapsamda:

  1. API'nin tarayıcılarda kullanılabilirliği ve uyumluluğu.
  2. scroll-start gibi yeni CSS API'leri üzerinde çalışın.
  3. snapChanged() gibi yeni JS etkinlikleri üzerinde çalışma.