Özet
CSS overscroll-behavior
özelliği, geliştiricilerin içeriğin üst/alt kısmına ulaşırken tarayıcının varsayılan taşma kaydırma davranışını geçersiz kılmasına olanak tanır. Kullanım örnekleri arasında, mobil cihazlarda yenilemek için çekme özelliğinin devre dışı bırakılması, fazla kaydırma parlaklığının ve lastik bant efektlerinin kaldırılması ve kalıcı/yer paylaşımı altında sayfa içeriğinin kaymasının önlenmesi yer alır.
Arka plan
Kaydırma sınırları ve kaydırma zinciri
Kaydırma, sayfayla etkileşim kurmanın en temel yollarından biridir. Ancak tarayıcının tuhaf varsayılan davranışları nedeniyle bazı kullanıcı deneyimi kalıplarıyla başa çıkmak zor olabilir. Örneğin, kullanıcının kaydırması gereken çok sayıda öğe içeren bir uygulama çekmecesini ele alalım. Alta geldiklerinde, tüketilecek başka içerik kalmadığından taşma kapsayıcısı kaydırmayı durdurur. Diğer bir deyişle, kullanıcı bir "kaydırma sınırına" ulaşır. Ancak kullanıcı kaydırmaya devam ederse neler olduğuna dikkat edin. Çekmece arkasındaki içerik kaydırmaya başlıyor. Kaydırma, üst kapsayıcı (örnekte ana sayfanın kendisi) tarafından yapılır.
Bu davranışa kaydırma zinciri adı verilir. Bu, tarayıcının içeriği kaydırırken görülen varsayılan davranışıdır. Çoğunlukla varsayılan ayar oldukça hoş olsa da, bazen istenen, hatta beklenmedik bir durum da olmayabilir. Kullanıcı, kaydırma sınırına ulaştığında bazı uygulamalar farklı bir kullanıcı deneyimi sunmak isteyebilir.
Yenilemek için çekme efekti
Yenilemek için çekme, Facebook ve Twitter gibi mobil uygulamalar tarafından yaygın olarak kullanılan sezgisel bir harekettir. Bir sosyal feed'i aşağı çekip serbest bırakmak, daha yeni yayınların yüklenmesi için yeni bir alan oluşturur. Bu özel kullanıcı deneyimi o kadar popüler hale geldi ki, Android'deki Chrome gibi mobil tarayıcılar da aynı etkiyi benimsedi. Sayfanın üst kısmından aşağı doğru hızlıca kaydırmak tüm sayfayı yeniler:
Twitter PWA gibi durumlarda yerel olarak yenilemek için çekme işlemini devre dışı bırakmak mantıklı olabilir. Neden? Bu uygulamada, muhtemelen kullanıcının sayfayı yanlışlıkla yenilemesini istemezsiniz. Ayrıca, çift yenileme animasyonu görme potansiyeli de vardır. Alternatif olarak, tarayıcının davranışını özelleştirmek ve sitenin marka bilinci oluşturma ile daha uyumlu hale getirmek daha iyi olabilir. Bu tür bir özelleştirmenin kolay üretilmesi zor olmasıdır. Geliştiriciler gereksiz JavaScript yazar,
pasif olmayan
dokunmatik dinleyiciler ekler (kaydırmayı engeller) veya (sayfanın taşmasını önlemek için) tüm sayfayı 100vw/vh
<div>
sabitler. Bu geçici çözümlerin, kaydırma performansı üzerinde doğrulanmış olumsuz etkileri vardır.
Daha iyisini yapabiliriz.
overscroll-behavior
ile tanışın
overscroll-behavior
özelliği, bir kapsayıcıyı (sayfanın kendisi dahil) fazla kaydırdığınızda ne olacağının davranışını kontrol eden yeni bir CSS özelliğidir. Kaydırma zincirini iptal etmek, yenilemek için çekme işlemini devre dışı bırakmak/özelleştirmek, iOS'te bant efektini devre dışı bırakmak (Safari'nin overscroll-behavior
özelliğini uyguladığında) ve daha fazlasını yapmak için bu özelliği kullanabilirsiniz.
En iyi tarafı, girişte bahsedilen ipuçları gibi overscroll-behavior
kullanmanın sayfa performansını olumsuz etkilememesidir.
Özellik üç olası değer alır:
- auto - Varsayılan. Öğede başlayan kaydırmalar üst öğelere yayılabilir.
- contain: Kaydırma zincirini önler. Kaydırmalar üst öğelere yayılmaz, ancak düğüm içindeki yerel etkiler gösterilir. Örneğin, Android'deki fazla kaydırma parlaklığı efekti veya iOS'teki lastik bant efekti, kullanıcılar kaydırma sınırına ulaştığında kullanıcılara bildirim gönderir. Not:
html
öğesindeoverscroll-behavior: contain
kullanmak, fazla kaydırmayla gezinme işlemlerini önler. - hiçbiri:
contain
ile aynıdır ancak düğümün kendi içinde fazla kaydırma efektlerini de önler (ör. Android fazla kaydırma parlaklığı veya iOS kauçuk bant oluşturma).
overscroll-behavior
hizmetinin nasıl kullanıldığını görmek için birkaç örnek inceleyelim.
Kaydırmaların sabit konumdaki bir öğeden çıkış yapmasını engelle
Sohbet kutusu senaryosu
Sayfanın alt kısmında bulunan sabit konumlu bir sohbet kutusu düşünün. Amaç, sohbet kutusunun bağımsız bir bileşen olmasıdır ve arkasındaki içerikten ayrı olarak kaydırılır. Ancak kaydırma zinciri nedeniyle kullanıcı sohbet geçmişindeki son mesaja ulaştığında doküman kaydırmaya başlar.
Bu uygulamada, sohbet kutusundan kaynaklanan kaydırmaların sohbet içinde kalması daha uygun olur. Bunu, sohbet mesajlarını barındıran öğeye overscroll-behavior: contain
ekleyerek gerçekleştirebiliriz:
#chat .msgs {
overflow: auto;
overscroll-behavior: contain;
height: 300px;
}
Esas olarak, sohbet kutusunun kaydırma bağlamı ile ana sayfa arasında mantıksal bir ayrım oluşturuyoruz. Sonuçta, kullanıcı sohbet geçmişinin en üstüne/en altına ulaştığında ana sayfa yerinde kalır. Sohbet kutusunda başlayan kaydırmalar yayılmaz.
Sayfa yer paylaşımı senaryosu
"Alt kaydırma" senaryosunun bir başka varyasyonu da içeriğin sabit konum yer paylaşımının arkasında kaydırıldığını görmenizdir. Ölü hediye
overscroll-behavior
verildi. Tarayıcı yardımcı olmaya çalışsa da
sitenin hatalı görünmesine yol açar.
Örnek - overscroll-behavior: contain
içeren ve içermeyen kalıcı iletişim kutusu:
Yenilemek için çekme işlemini devre dışı bırakma
Yenilemek için çekme işlemini devre dışı bırakmak tek bir CSS satırıdır. Görüntü alanı tanımlayan öğenin tamamında
kaydırmayı zincirleme işlemi önlemeniz yeterlidir. Çoğu durumda bu <html>
veya <body>
olur:
body {
/* Disables pull-to-refresh but allows overscroll glow effects. */
overscroll-behavior-y: contain;
}
Bu basit eklemeyle sohbet kutusu demosundaki iki kez yenilemek için çekme animasyonlarını düzelttik ve bunun yerine daha düzgün bir yükleme animasyonu kullanan özel bir efekt uygulayabiliyoruz. Gelen kutusu yenilendikçe gelen kutusunun tamamı da bulanıklaştırılır:
Tam kodun snippet'ini burada bulabilirsiniz:
<style>
body.refreshing #inbox {
filter: blur(1px);
touch-action: none; /* prevent scrolling */
}
body.refreshing .refresher {
transform: translate3d(0,150%,0) scale(1);
z-index: 1;
}
.refresher {
--refresh-width: 55px;
pointer-events: none;
width: var(--refresh-width);
height: var(--refresh-width);
border-radius: 50%;
position: absolute;
transition: all 300ms cubic-bezier(0,0,0.2,1);
will-change: transform, opacity;
...
}
</style>
<div class="refresher">
<div class="loading-bar"></div>
<div class="loading-bar"></div>
<div class="loading-bar"></div>
<div class="loading-bar"></div>
</div>
<section id="inbox"><!-- msgs --></section>
<script>
let _startY;
const inbox = document.querySelector('#inbox');
inbox.addEventListener('touchstart', e => {
_startY = e.touches[0].pageY;
}, {passive: true});
inbox.addEventListener('touchmove', e => {
const y = e.touches[0].pageY;
// Activate custom pull-to-refresh effects when at the top of the container
// and user is scrolling up.
if (document.scrollingElement.scrollTop === 0 && y > _startY &&
!document.body.classList.contains('refreshing')) {
// refresh inbox.
}
}, {passive: true});
</script>
Fazla kaydırma parlaklığını ve lastik bant efektlerini devre dışı bırakma
Kaydırma sınırına ulaşırken geri dönme efektini devre dışı bırakmak için overscroll-behavior-y: none
işlevini kullanın:
body {
/* Disables pull-to-refresh and overscroll glow effect.
Still keeps swipe navigations. */
overscroll-behavior-y: none;
}
Tam demo
Hepsini bir araya getiren tam chatbox demosu, özel bir yenilemek için çekme animasyonu oluşturmak ve kaydırmaların sohbet kutusu widget'ından çıkış yapmasını devre dışı bırakmak için overscroll-behavior
kullanır. Bu yöntem, CSS overscroll-behavior
olmasaydı elde edilmesi zor olacak ideal bir kullanıcı deneyimi sağlar.