Özet
CSS overscroll-behavior
özelliği, geliştiricilerin içeriğin üst/alt kısmına ulaşıldığında tarayıcının varsayılan taşma kaydırma davranışını geçersiz kılmasına olanak tanır. Mobil cihazlarda yenile düğmesine basarak yenileme özelliğini devre dışı bırakma, kaydırma sırasında parlama ve lastik bant efektlerini kaldırma ve bir modal/yer paylaşımının altındayken sayfa içeriğinin kaydırılmasını önleme, bu özelliğin kullanım alanları arasındadır.
Arka plan
Kaydırma sınırları ve kaydırma zincirleme
Sayfayla etkileşim kurmanın en temel yollarından biri kaydırmadır. Ancak tarayıcının tuhaf varsayılan davranışları nedeniyle belirli kullanıcı deneyimi kalıplarıyla başa çıkmak zor olabilir. Örneğin, kullanıcının kaydırması gerekebilecek çok sayıda öğenin bulunduğu bir uygulama çekmecesini ele alalım. Kullanıcılar en alta ulaştığında, taşma kapsayıcısı kaydırmayı durdurur çünkü tüketilebilecek başka içerik yoktur. Diğer bir deyişle, kullanıcı bir "kaydırma sınırına" ulaşır. Ancak kullanıcı sayfayı kaydırmaya devam etmeye devam ederse ne olacağına dikkat edin. Çekmecenin arkasındaki içerik kaydırmaya başlar. Kaydırma işlemi, üst kapsayıcı (örneğin, ana sayfa) tarafından devralınır.
Bu davranışın adı kaydırma zincirleme. Tarayıcının içerik kaydırırken varsayılan davranışıdır. Varsayılan değer genellikle oldukça iyidir ancak bazen istenmeyebilir veya beklenmeyebilir. Bazı uygulamalar, kullanıcı kaydırma sınırına ulaştığında farklı bir kullanıcı deneyimi sunmak isteyebilir.
Yenilemek için aşağı çekme efekti
Yenilemek için çekme, Facebook ve Twitter gibi mobil uygulamalar tarafından popüler hale gelen sezgisel bir harekettir. Sosyal medya özet akışını aşağı çekip bıraktığınızda daha yeni gönderilerin yüklenmesi için yeni alan açılır. Bu kullanıcı deneyimi o kadar popüler oldu ki Android'deki Chrome gibi mobil tarayıcılar da aynı efekti benimsedi. Sayfanın üst kısmından aşağı doğru kaydırdığınızda tüm sayfa yenilenir:
Twitter PWA gibi durumlarda, yerel olarak yenilemek için kaydırma 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 da görebilirsiniz. Alternatif olarak, tarayıcının işlemini özelleştirmek ve sitenin markasına daha uygun hale getirmek daha iyi olabilir. Bu tür özelleştirmelerin yapılmasının zor olması talihsiz bir durumdur. Geliştiriciler gereksiz JavaScript yazar, pasif olmayan dokunma dinleyicileri ekler (kaydırma işlevini engeller) veya sayfanın tamamını 100vw/vh <div>
içine sıkıştırır (sayfanın taşmasını önlemek için). Bu geçici çözümlerin, kaydırma performansı üzerinde iyi belgelenmiş olumsuz etkileri vardır.
Daha iyisini yapabiliriz.
overscroll-behavior
ile tanışın
overscroll-behavior
mülk, 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 zincirleme işlemini iptal etmek, yenilemek için çekme işlemini devre dışı bırakmak/özelleştirmek, iOS'te lastik bant efektlerini devre dışı bırakmak (Safari overscroll-behavior
'ü uyguladığında) ve daha fazlası için bu özelliği kullanabilirsiniz.
En iyi yanı da, girişte bahsedilen saldırılar gibi overscroll-behavior
kullanımının sayfa performansını olumsuz şekilde etkilememesidir.
Özellik üç olası değer alır:
- auto: Varsayılan. Öğede gerçekleşen kaydırmalar, üst öğelere yayılabilir.
- contain: Kaydırma zincirlemeyi engeller. Kaydırmalar üst öğelere yayılmaz ancak düğüm içindeki yerel etkiler gösterilir. Örneğin, Android'de kaydırma sınırını aştığında kullanıcıyı bilgilendiren kaydırma ışıltısı efekti veya iOS'te kullanıcıyı kaydırma sınırına ulaştığında bilgilendiren lastik bant efekti. Not:
html
öğesindeoverscroll-behavior: contain
kullanılması, kaydırma çubuğuyla aşırı kaydırma gezinme işlemlerini engeller. - none:
contain
ile aynıdır ancak düğümün kendi içinde fazla kaydırma efektlerini de önler (ör. Android fazla kaydırma parlaması veya iOS kauçuk bant).
overscroll-behavior
işlevinin nasıl kullanıldığını görmek için bazı örneklere göz atalım.
Kaydırmaların sabit konum öğesinden kaçmasını önleme
Sohbet kutusu senaryosu
Sayfanın alt kısmında bulunan sabit yerleştirilmiş bir sohbet kutusu düşünün. Amaç, sohbet kutusunun bağımsız bir bileşen olması ve arkasındaki içerikten ayrı olarak kaymasıdır. Ancak kaydırma zinciri nedeniyle, kullanıcı sohbet geçmişindeki son iletiye ulaştığında belge kaydırmaya başlar.
Bu uygulamada, sohbet kutusunda başlayan kaydırmaların sohbet içinde kalmasının daha uygun olduğu düşünülmektedir. Bunu, sohbet mesajlarını içeren öğeye overscroll-behavior: contain
ekleyerek yapabiliriz:
#chat .msgs {
overflow: auto;
overscroll-behavior: contain;
height: 300px;
}
Temel olarak, sohbet kutusunun kaydırılabilir bağlamı ile ana sayfa arasında mantıksal bir ayrım oluşturuyoruz. Sonuç olarak, kullanıcı sohbet geçmişinin en üstüne/altına ulaştığında ana sayfa yerinde kalır. Sohbet kutusunda başlayan kaydırmalar diğer sayfalara yayılmaz.
Sayfa yerleşimi senaryosu
"Ekranın altında kaydırma" senaryosunun bir başka varyasyonu da sabit konum yer paylaşımının arkasında kaydırılan içeriktir. overscroll-behavior
hediyesi kazanmak için Tarayıcı yardımcı olmaya çalışıyor ancak sitenin hatalı görünmesine neden oluyor.
Örnek - overscroll-behavior: contain
içeren ve içermeyen kalıcı:
Yenilemek için çekme seçeneğini devre dışı bırakma
Yenilemek için sürükle işlemini devre dışı bırakmak tek bir CSS satırıdır. Görünüm alanını tanımlayan öğenin tamamında kaydırma zincirleme işlemini engellemeniz yeterlidir. Çoğu durumda bu <html>
veya <body>
'tır:
body {
/* Disables pull-to-refresh but allows overscroll glow effects. */
overscroll-behavior-y: contain;
}
Bu basit eklemeyle, sohbet kutusu demosundaki yenileme için ekranı iki kez çekme animasyonlarını düzelttik ve bunun yerine daha düzenli bir yükleme animasyonu kullanan özel bir efekt uygulayabiliriz. Gelen kutusu yenilenirken gelen kutusunun tamamı da bulanıklaştırılır:
Tam kodun bir 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>
Kaydırma sırasında parlama ve lastik bant efektlerini devre dışı bırakma
Kaydırma sınırına ulaştığınızda geri sekme efektini devre dışı bırakmak için overscroll-behavior-y: none
komutunu kullanın:
body {
/* Disables pull-to-refresh and overscroll glow effect.
Still keeps swipe navigations. */
overscroll-behavior-y: none;
}
Tam demo
Tüm bunları bir araya getiren tam sohbet kutusu demosu, özel bir sürükleyerek yenileme animasyonu oluşturmak ve kaydırmaların sohbet kutusu widget'ından kaçmasını engellemek için overscroll-behavior
kullanır. Bu, CSS olmadan elde etmenin zor olacağı optimum bir kullanıcı deneyimi sağlaroverscroll-behavior
.