CSS Scroll Snap ile iyi kontrol edilmiş kaydırma

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

Robert Flack
Robert Flack
Majid Valipour
Majid Valipour

CSS Kaydırma Tutturması özelliği, web geliştiricilerin kaydırma tutturma konumları bildirerek iyi kontrol edilen kaydırma deneyimleri oluşturmalarını sağlar. Sayfalandırılmış makaleler ve resim ruloları bu durumun 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ırarak tutturma özelliğinin durumu

Kaydırma, web'deki içerikle etkileşim kurmanın popüler ve doğal bir yoludur. Aynı anda ekranda görünenden daha fazla bilgiye erişim sağlama konusunda platformun yerel yöntemidir ve sınırlı ekran alanına sahip mobil platformlarda özellikle hayati önem taşır. Bu nedenle, web yazarlarının içerikleri derin hiyerarşiler yerine kaydırılabilir düz listeler halinde organize etmeyi giderek daha fazla tercih etmeleri şaşırtıcı değildir.

Kaydırmanın en önemli dezavantajı, kesinlik eksikliğidir. Kaydırmanın bir paragrafa veya cümleye hizalanması nadirdir. Kaydırma sayfanın veya resmin ortasında bittiğinde ve sayfa kısmen görünür halde kaldığında bu durum, anlamlı sınırlara sahip sayfalara ayrılmış veya öğeli içeriklerde daha da belirgindir. Bu kullanım alanları, iyi kontrol edilen bir kaydırma deneyiminden faydalanır.

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

CSS Scroll Snap, web yazarlarının her bir kaydırma kapsayıcısını sınırlarıyla işaretlemelerine olanak tanır. Tarayıcılar daha sonra kaydırma işleminin özelliklerine, kaydırma kapsayıcısının düzenine, görünürlüğüne ve tutturma konumlarının ayrıntılarına bağlı olarak en uygun bitiş konumunu seçer ve ardından ona sorunsuzca animasyon uygular. Önceki örneğimize dönecek olursak, kullanıcı bantta kaydırmayı bitirdiğinde görünür resmi yerine oturur. JavaScript'in kaydırma ayarlaması gerekmez.

Bir resim rulosuyla css kaydırma yapıştırmasını kullanmaya ilişkin örnek.
Bir resim rulosuyla css kaydırma tutturma kullanımı örneği. Burada kaydırmaya tutturma, kaydırma işleminin sonunda, resim yatay merkezin kaydırma kapsayıcısının yatay merkeziyle aynı hizada olmasını sağlar.

CSS Kaydırma Kenarlığı

Kaydırma tutturma, kaydırma işlemi tamamlandığında kaydırma ofsetinin tercih edilen tutturma konumuna gelecek şekilde ayarlanmasıdır.

Kaydırma kapsayıcısı, scroll-snap-type özelliği kullanılarak kaydırmaya yapışmaya dahil edilebilir. Bu, tarayıcıya bu kaydırma kapsayıcısını, alt öğeleri tarafından oluşturulan tutturma konumlarına tutturmayı değerlendirmesi gerektiğini bildirir. scroll-snap-type, kaydırmanın gerçekleştiği ekseni belirler: x, y veya both ve tutturma sıkılığı: mandatory, proximity. Bunlara daha sonra değineceğiz.

Bir öğe üzerinde istenen bir hizalama bildirilerek tutturma konumu oluşturulabilir. Bu konum, en yakın üst öğe kaydırma kapsayıcısının ve öğenin belirtilen eksende belirtildiği gibi hizalandığı kaydırma ofsetidir. Her bir eksende şu hizalamalar mümkündür: start, end, center.

start hizalaması, kaydırma kapsayıcısının tutturma noktası başlangıç kenarının, öğe tutturma alanının 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 bitiş kenarının veya merkezinin öğe tutturma alanının bitiş kenarı veya ortasıyla 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ırarak tutturma için yaygın bir kullanım örneği, bir resim bandıdır. Örneğin, siz kaydırdıkça her resme tutturulan bir yatay resim bandı oluşturmak için kaydırma kapsayıcısının yatay eksende zorunlu bir scroll-snap-type içermesini sağlayabiliriz. Yapışmanın, görüntüyü atlı karınca içinde ortalamasını sağlamak için her resmi scroll-snap-align: center değerine ayarlayın.

#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>

Tutturma konumları bir öğeyle ilişkili olduğundan tutturma algoritması, öğeye ve kaydırma kapsayıcısı boyutuna göre ne zaman ve nasıl tutturulacağı konusunda akıllı davranabilir. Örneğin, bir resmin banttan daha büyük olduğu durumu ele alalım. Naif tutturma algoritması, kullanıcının tam resmi görmek için ekranı kaydırmasını engelleyebilir. Ancak spesifikasyon, bu durumu algılamak ve kullanıcının yalnızca kenarlarına yapışarak görüntü içinde serbestçe gezinmesine izin vermek için uygulamalar gerektirir.

Demoyu göster | Kaynak

Örnek: yolculuk yapılan ürün sayfası

Kaydırarak tutturma özelliğinden yararlanabilecek bir başka yaygın durum da, örneğin tipik bir ürün sayfası gibi, dikey olarak kaydırılabilen birden çok mantıksal bölüme sahip sayfalardır. scroll-snap-type: y proximity;, bu gibi durumlar için daha doğal bir tercihtir. Kullanıcı sayfayı belirli bir bölümün ortasına kaydırdığında bu özellikten etkilenmez, ancak kullanıcı ekranı yeterince yakına kaydırdığında yeni bir bölüme tutturur ve dikkat ç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 bir üst başlık bulunur. Tasarım, kullanıcılara yukarıdaki içerik hakkında bir tasarım ipucu vermek amacıyla kaydırma kapsayıcısı kapandığında üst bölümün bir kısmının görünür kalmasını da istedi.

scroll-padding özelliği, kaydırma kapsayıcısının veya anlık görüntü tutturma işleminin etkili görüntülenebilir bölgesini ayarlamak için kullanılabilen ve kaydırmaya tutturma hizalamaları hesaplanırken kullanılan yeni bir css özelliğidir. Özellik, kaydırma kapsayıcısının dolgu kutusuna karşı bir iç küme tanımlar. Örneğimizde en üste 15vh ilave ek yerleştirilmiştir. Böylece, tarayıcıya kaydırma kapsayıcısı için dikey başlangıç kenarı olarak kaydırma kapsayıcısının üst kenarının altındaki daha düşük bir konumu (15vh) dikkate alması talimatı verilir. Tutturma işlemi sırasında, tutturma hedefi öğesinin başlangıç kenarı bu yeni konumla boşaltılır ve böylece yukarıda boşluk bırakılır.

scroll-margin özelliği, scroll-padding uygulamasının tutturma kaydırma kapsayıcısındaki işlevine benzer şekilde tutturma hedefi etkin kutusunu ayarlamak için kullanılan çıkış miktarını tanımlar.

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 sadece kaydırma yapraklama yapmadıkları için kasıtlıdır. Örneğin Chrome, PageDown ve PageUp gibi sayfa kaydırma işlemleri için sayfa boyutunu ve Element.scrollIntoView() işlemi için kaydırma miktarını hesaplarken bunları da dikkate alır.

Demoyu göster | Kaynak

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

DOM Kaydırma API'sı

Kaydırma yapışma, komut dosyası tarafından başlatılanlar dahil olmak üzere tüm kaydırma işlemlerinden sonra gerçekleşir. Element.scrollTo gibi API'ler kullandığınızda, tarayıcı işlemin istenen kaydırma konumunu hesaplar ve ardından en son tutturulan konumu bulmak için uygun tutturma mantığını uygular. Dolayısıyla, kullanıcı komut dosyasının tutturma işlemi için manuel hesaplamalar yapmasına gerek yoktur.

Kesintisiz kaydırma

Kesintisiz kaydırma, programlı kaydırma işleminin davranışını kontrol ederken, kaydırma tutturma işleminin hedefini belirler. Kaydırmanın dikey yönlerini kontrol ettiği için birbirlerini tamamlayarak kullanılabilirler.

Fazla kaydırma davranışı

Aşırı kaydırma davranışı API'si kaydırmanın birden fazla öğede nasıl zincirlendiğini kontrol eder ve kaydırmadan etkilenmez.

Uyarılar ve en iyi uygulamalar

Hedef öğeler arasında geniş aralıklı boşluklar varsa zorunlu tutturmayı kullanmaktan kaçının. Bu durum, tutturma konumları arasındaki içeriğin erişilemez hale gelmesine neden olabilir.

Çoğu durumda, kaydırma yapışma özelliği özellik algılama işlemine 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 mevcut olan 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 kaydırma API'lerinin her zaman istenen kaydırma ofsetinde tamamlandığını varsaymayın. Kaydırma tutturma, programlı kaydırma tamamlandıktan sonra kaydırma ofsetini ayarlayabilir. Kaydırma başka nedenlerden dolayı kesintiye uğrayabileceğinden, kaydırma tutturma işleminden önce bile bunun iyi bir varsayım olmadığını unutmayın. Bu durum özellikle kaydırmanın yapışma işleminde söz konusudur.

Gelecekteki çalışmalar

Chrome ekibi tarafından yakın zamanda yapılan bir ankette kaydırma deneyimi, odak noktasıydı. Anket sonuçları, eklenti kitaplıkları ile CSS arasındaki boşluğu kapatmak için ek çalışma gerektiren çeşitli alanlar olduğunu belirledi. Önümüzdeki günlerde yapılması planlanan çalışmalar scroll-snap ile ilgili olarak şu konulara odaklanacak:

  1. API kullanılabilirliği ve tarayıcılar arasında uyumluluk.
  2. scroll-start gibi yeni CSS API'lerinde çalışın.
  3. snapChanged() gibi yeni JS etkinlikleri üzerinde çalışın.