Ö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. Kullanım alanları arasında mobil cihazlarda yenilemeyi çekme ö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ı engelleme yer alı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ı kaydırmaya devam ederse ne olduğuna dikkat edin. Çekmecenin arkasındaki içerik kaydırmaya başlar. Kaydırma işlemi, üst kapsayıcı (örnekte 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ı bir kaydırma sınırına ulaştığında farklı bir kullanıcı deneyimi sunmak isteyebilir.
Yenilemek için aşağı çekme efekti
Ekranı yukarı kaydırarak yenileme, Facebook ve Twitter gibi mobil uygulamalar tarafından yaygınlaştırılan 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ğı kaydırarak sayfanın tamamını yenileyebilirsiniz:
Twitter PWA gibi durumlarda, yerel olarak yenilemek için kaydırma işlemini devre dışı bırakmak mantıklı olabilir. Neden? Bu uygulamada, kullanıcının sayfayı yanlışlıkla yenilemesini istemezsiniz. Ayrıca, iki kez yenileme animasyonunu da görebilirsiniz. Alternatif olarak, tarayıcının işlemini sitenin markasına daha uygun olacak şekilde özelleştirmek de iyi bir fikir 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ı, overscroll-behavior
'yi kullanmak, girişte bahsedilen hilelerin aksine sayfa performansını olumsuz etkilemez.
Özellik üç olası değer alır:
- auto: Varsayılan. Öğeden kaynaklanan 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 kendisindeki aşırı kaydırma efektlerini de (ör. Android aşırı kaydırma parlaması veya iOS esnek bant) engeller.
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 sabit konumlu 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 yer paylaşımı 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 modal:
Yenilemek için aşağı çekme özelliğ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şır:
Tam kodun bir snippet'ini aşağıda 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 sonu parlama ve lastik bant efektlerini devre dışı bırakma
Kaydırma sınırına ulaşıldığında sıçrama efektini devre dışı bırakmak için overscroll-behavior-y: none
:
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 yenile düğmesine dokunarak 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
.