CSS Scroll Snap ile iyi kontrol edilmiş kaydırma

Kaydırma sabitleme konumlarını bildirerek iyi kontrol edilen kaydırma deneyimleri oluşturun.

Robert Flack
Robert Flack
Majid Valipour
Majid Valipour

CSS Kaydırma Sabitlemesi özelliği, web geliştiricilerin kaydırma sabitleme konumlarını tanımlayarak iyi kontrol edilen kaydırma deneyimleri oluşturmasına olanak tanır. Sayfalara ayrılmış makaleler ve resim bantları, bu tür içeriklerin yaygın olarak kullanılan iki örneğidir. 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 sabitleme özelliğinin avantajları

Ekranı kaydırma, web'deki içeriklerle etkileşim kurmanın popüler ve doğal bir yoludur. Platformun, ekranda aynı anda görünenden daha fazla bilgiye erişim sağlamanın doğal yoludur. Özellikle ekran alanı sınırlı olan mobil platformlarda hayati önem taşır. Bu nedenle, web yazarlarının içeriği derin hiyerarşiler yerine kaydırılabilir düz listelerde düzenlemeyi tercih etmesi şaşırtıcı değil.

Kaydırma işleminin en büyük dezavantajı, hassasiyet eksikliğidir. Kaydırma işleminin bir paragraf veya cümleyle hizalanması nadiren gerçekleşir. Bu durum, sayfanın veya resmin ortasında kaydırma işlemi sona erdiğinde ve içerik kısmen görünür kaldığında, anlamlı sınırları olan sayfalara ayrılmış veya listelenmiş içeriklerde daha da belirgindir. Bu kullanım alanları, iyi kontrol edilen bir kaydırma deneyiminden yararlanır.

Web geliştiricileri, bu eksikliği gidermek için uzun süredir kaydırma işlemini kontrol etmek üzere JavaScript tabanlı çözümlere güveniyordu. Ancak JavaScript tabanlı çözümler, kaydırma özelleştirmesi için temel öğelerin olmaması veya birleştirilmiş kaydırmaya erişim olmaması nedeniyle tam doğruluk sağlayan 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 sona ereceği sınırlarla işaretlemelerine olanak tanır. Tarayıcılar daha sonra kaydırma işleminin ayrıntılarına, kaydırma kapsayıcısının düzenine ve görünürlüğüne, sabitleme konumlarının ayrıntılarına bağlı olarak en uygun bitiş konumunu seçer ve ardından bu konuma sorunsuz bir şekilde animasyonla gider. Önceki örneğimize dönecek olursak, kullanıcı bandı kaydırmayı tamamladığında, görünür resim yerine oturur. JavaScript'in kaydırma ayarlaması yapması gerekmez.

CSS kaydırma sabitlemesini resim bandıyla kullanma örneği.
CSS kaydırma sabitlemenin resim rulosuyla birlikte kullanılmasına ilişkin örnek. Burada kaydırma sabitleme, kaydırma işleminin sonunda resmin yatay merkezinin kaydırma kapsayıcının yatay merkeziyle hizalanmasını sağlar.

CSS Kaydırma Kilidi

Kaydırma sabitleme, kaydırma işlemi sona erdiğinde kaydırma kapsayıcının kaydırma ofsetini tercih edilen bir sabitleme konumuna ayarlama işlemidir.

scroll-snap-type özelliği kullanılarak kaydırma kapsayıcısında kaydırma sabitleme etkinleştirilebilir. Bu, tarayıcıya bu kaydırma kapsayıcısını alt öğeleri tarafından oluşturulan sabitleme konumlarına sabitlemesi gerektiğini söyler. scroll-snap-type, kaydırma işleminin gerçekleştiği ekseni (x, y veya both) ve sabitleme sıkılığını (mandatory, proximity) belirler. Bu konu hakkında daha sonra daha fazla bilgi vereceğiz.

Bir öğede istenen bir hizalama açıklanarak sabitleme konumu oluşturulabilir. Bu konum, en yakın üst öğe kaydırma kapsayıcısı ile öğenin, belirli bir eksen için belirtildiği şekilde hizalandığı kaydırma ofsetidir. Her eksende şu hizalamalar mümkündür: start, end, center.

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

Yatay kaydırma ekseninde çeşitli hizalamalar örneği.

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

Kaydırmayla sabitleme özelliğinin yaygın kullanım alanlarından biri resim bandıdır. Örneğin, siz kaydırırken her resme sabitlenen yatay bir resim bandı oluşturmak için kaydırma kapsayıcısının yatay eksende zorunlu bir scroll-snap-type değerine sahip olmasını belirtebiliriz. Sabitlemenin resmi bandın ortasına yerleştirmesini 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>

Sabitleme konumları bir öğeyle ilişkilendirildiğinden, sabitleme algoritması öğe ve kaydırma kapsayıcısı boyutu dikkate alınarak ne zaman ve nasıl sabitleneceği konusunda akıllıca davranabilir. Örneğin, bir resmin rulodan daha büyük olduğu durumu düşünün. Basit bir yakalama algoritması, kullanıcının resmin tamamını görmek için ekranı kaydırmasını engelleyebilir. Ancak özellik, bu durumu algılayan ve kullanıcının yalnızca kenarlarına dokunarak söz konusu resimde serbestçe kaydırmasına olanak tanıyan uygulamalar gerektirir.

Demoyu görüntüleyin | Kaynak

Örnek: Bir ürün yolculuğu sayfası

Kaydırmayla sabitlemeden yararlanabilecek yaygın bir diğer durum da, dikey olarak kaydırılacak birden fazla mantıksal bölüm içeren sayfalardır (ör. tipik bir ürün sayfası). scroll-snap-type: y proximity;, bu tür durumlar için daha uygundur. Kullanıcı belirli bir bölümün ortasına kaydırdığında müdahale etmez ancak yeterince yakın kaydırdığında yeni bir bölüme odaklanır ve dikkati bu bölüme çeker.

Bunu ş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, kaydırma kapsayıcısı sabitlendiğinde üst bölümün bir kısmının görünür kalması da istendi. Böylece kullanıcılara yukarıdaki içerikle ilgili bir tasarım ipucu sağlanmış olacaktı.

scroll-padding özelliği, kaydırma kapsayıcısının veya sabitleme noktasının etkili görüntülenebilir bölgesini ayarlamak için kullanılabilen yeni bir CSS özelliğidir. Bu özellik, kaydırma sabitleme hizalamalarını hesaplarken kullanılır. Bu özellik, kaydırma kapsayıcısının dolgu kutusuna karşı bir içe yerleştirilme tanımlar. Örneğimizde, 15vh ek içe yerleştirilmiş öğe üst tarafa eklenmiştir. Bu öğe, tarayıcıya kaydırma sabitleme için dikey başlangıç kenarı olarak kaydırma kapsayıcısının üst kenarının altındaki 15vh daha düşük bir konumu dikkate almasını söyler. Sabitleme sırasında, sabitleme hedefi öğesinin başlangıç kenarı bu yeni konumla aynı hizada olur ve böylece yukarıda boşluk kalır.

scroll-margin mülkünde, scroll-padding'ın sabit kaydırma kapsayıcısında işleyiş şekline benzer şekilde sabitleme hedefinin etkili kutusunu ayarlamak için kullanılan başlangıç miktarı tanımlanır.

Bu iki mülkte "snap" kelimesinin bulunmadığını fark etmiş olabilirsiniz. Bu, ilgili tüm kaydırma işlemleri için kutuyu değiştirdikleri ve yalnızca kaydırma sabitlemesi yapmadıkları için bilinçli olarak yapılır. Örneğin, Chrome; Sayfa Aşağı ve Sayfa Yukarı gibi sayfa kaydırma işlemleri için sayfa boyutunu hesaplarken ve Element.scrollIntoView() işlemi için kaydırma miktarını hesaplarken bunları hesaba katar.

Demoyu görüntüleyin | Kaynak

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

DOM Scrolling API

Kaydırma sabitleme, komut dosyası tarafından başlatılanlar da dahil olmak üzere tüm kaydırma işlemlerinden 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 nihai sabitleme konumunu bulmak için uygun sabitleme mantığını uygular. Bu nedenle, kullanıcı komut dosyasının, sabitleme için manuel hesaplamalar yapmasına gerek yoktur.

Sorunsuz kaydırma

Sorunsuz kaydırma, programatik kaydırma işleminin davranışını kontrol ederken kaydırma sabitleme işlemi hedefini belirler. Kaydırma işleminin dik açıdaki yönlerini kontrol ettikleri için birlikte kullanılabilir ve birbirlerini tamamlayabilirler.

Kaydırma sonu davranışı

Overscroll behavior API, kaydırma işleminin birden fazla öğe arasında nasıl zincirleneceğini kontrol eder ve kaydırma anında sabitlenmeden etkilenmez.

Uyarılar ve en iyi uygulamalar

Hedef öğeler birbirinden uzak olduğunda zorunlu sabitlemeyi kullanmaktan kaçının. Bu durum, sabitleme konumları arasındaki içeriğe erişilememesine neden olabilir.

Çoğu durumda, kaydırma sabitleme özelliği, özellik algılamasına gerek kalmadan 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 değerini 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 programlı olarak kaydırılan API'lerin her zaman istenen kaydırma ofsetinde sona erdiğini varsaymayın. Kaydırma sabitleme, programatik kaydırma tamamlandıktan sonra kaydırma ofsetini ayarlayabilir. Kaydırma işlemi başka nedenlerle kesintiye uğramış olabileceğinden, kaydırma anında duraklatma özelliğinden önce bile bunun iyi bir varsayım olmadığını unutmayın. Ancak bu durum özellikle kaydırma anında duraklatma özelliğinde geçerlidir.

Gelecekte yapılacak çalışmalar

Chrome ekibinin kısa süre önce yaptığı bir ankette kaydırma deneyimi ele alındı. Anket sonuçları, eklenti kitaplıkları ile CSS arasındaki boşluğu kapatmak için ek çalışma gerektiren çeşitli alanlar belirledi. Yaklaşan çalışmalarda scroll-snap'ye odaklanılacak. Bu çalışmalar arasında şunlar yer alıyor:

  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ışın.