TL;DR
Properti overscroll-behavior
CSS memungkinkan developer mengganti
perilaku scroll luapan default browser saat mencapai bagian atas/bawah
saat ini. Kasus penggunaan mencakup menonaktifkan fitur pull-to-refresh
di perangkat seluler, menghapus efek overscroll glow dan rubberbanding,
dan mencegah konten halaman di-scroll saat berada di bawah modal/overlay.
Latar belakang
Batas scroll dan rantai scroll
Menggulir adalah salah satu cara paling mendasar untuk berinteraksi dengan suatu laman, tetapi pola UX tertentu bisa sulit untuk ditangani karena keunikan browser perilaku default. Sebagai contoh, ambil panel samping aplikasi dengan sejumlah besar item yang mungkin harus di-scroll oleh pengguna. Saat mencapai bagian bawah, penampung tambahan akan berhenti men-scroll karena tidak ada lagi konten yang akan digunakan. Dengan kata lain, pengguna mencapai "batas scroll". Tetapi perhatikan apa yang terjadi jika pengguna terus men-scroll. Konten di belakang panel samping mulai di-scroll. Scroll diambil alih oleh penampung induk; halaman utama itu sendiri dalam contoh.
Ternyata perilaku ini disebut rantai scroll; perilaku default browser saat men-scroll konten. Sering kali {i>default-<i}nya cukup bagus, tapi terkadang tidak diinginkan atau bahkan tidak terduga. Aplikasi tertentu mungkin ingin memberikan pengalaman pengguna yang berbeda saat pengguna mencapai batas scroll.
Efek tarik untuk memuat ulang
Tarik untuk menyegarkan adalah gestur intuitif yang dipopulerkan oleh aplikasi seluler seperti Facebook dan Twitter. Menarik ke umpan sosial dan merilisnya akan membuat ruang untuk memuat postingan terbaru lainnya. Faktanya, UX khusus ini telah menjadi sangat populer sehingga browser seluler seperti Chrome di Android telah mengadopsi efek yang sama. Menggeser ke bawah di bagian atas halaman akan menyegarkan seluruh halaman:
Untuk situasi seperti PWA Twitter,
mungkin masuk akal untuk menonaktifkan tindakan pull-to-refresh native. Mengapa? Di sini
Anda tidak ingin pengguna memuat ulang halaman secara tidak sengaja. Ada
juga potensi untuk melihat animasi muat ulang ganda. Atau, mungkin
lebih baik menyesuaikan tindakan browser, menyelaraskannya lebih dekat dengan
{i>branding.<i} Bagian yang kurang menguntungkan adalah bahwa
jenis penyesuaian ini telah
sulit untuk dilakukan. Developer akhirnya menulis {i>
JavaScript <i}yang tidak perlu, menambahkan
non-pasif
pendengar sentuh (yang memblokir pengguliran), atau menempelkan seluruh laman dalam tegangan 100vw/vh
<div>
(untuk mencegah halaman kelebihan beban). Solusi ini memiliki
negatif yang terdokumentasi dengan baik
terhadap performa scroll.
Kita bisa melakukan yang lebih baik.
Memperkenalkan overscroll-behavior
Properti overscroll-behavior
adalah fitur CSS baru yang mengontrol
perilaku yang terjadi saat Anda men-scroll penampung secara berlebihan (termasuk
halaman itu sendiri). Anda dapat menggunakannya untuk membatalkan rantai scroll, menonaktifkan/menyesuaikan
tindakan tarik untuk memuat ulang, menonaktifkan efek rubberbanding di iOS (saat Safari
menerapkan overscroll-behavior
), dan lainnya.
Bagian terbaiknya adalah penggunaan overscroll-behavior
tidak berdampak buruk
performa halaman seperti tips yang disebutkan di bagian pengantar.
Properti ini memiliki tiga kemungkinan nilai:
- auto - Default. Scroll yang berasal dari elemen dapat diterapkan ke elemen ancestor.
- contain - mencegah rantai scroll. Scroll tidak diterapkan ke ancestor,
tetapi efek lokal dalam node ditampilkan. Misalnya, efek cahaya overscroll
di Android atau efek rubberbanding di iOS yang memberi tahu pengguna
saat mereka mencapai batas scroll. Catatan: menggunakan
overscroll-behavior: contain
pada elemenhtml
akan mencegah tindakan navigasi overscroll. - none - sama seperti
contain
tetapi juga mencegah efek overscroll dalam node itu sendiri (mis. glow overscroll Android atau rubberbanding iOS).
Mari kita pelajari beberapa contoh untuk melihat cara menggunakan overscroll-behavior
.
Mencegah scroll keluar dari elemen posisi tetap
Skenario kotak chat
Pertimbangkan kotak chat yang diposisikan tetap di bagian bawah halaman. Tujuannya adalah bahwa kotak chat adalah komponen mandiri dan di-scroll secara terpisah dari konten di belakangnya. Namun, karena rantai scroll, dokumen mulai di-scroll segera setelah pengguna mengklik pesan terakhir dalam chat sejarah.
Untuk aplikasi ini, akan lebih tepat untuk memiliki scroll yang berasal dari
kotak chat tetap ada dalam percakapan. Kita dapat mewujudkannya
dengan menambahkan
overscroll-behavior: contain
ke elemen yang menyimpan pesan chat:
#chat .msgs {
overflow: auto;
overscroll-behavior: contain;
height: 300px;
}
Pada dasarnya, kita membuat pemisahan logis antara konteks scroll chatbox dan halaman utama. Hasil akhirnya adalah halaman utama tetap berada di tempatnya saat pengguna mencapai bagian atas/bawah histori chat. Scroll yang dimulai di chatbox tidak akan menyebar.
Skenario overlay halaman
Variasi lain dari "underscroll" skenario ini adalah ketika
Anda melihat konten
men-scroll di belakang overlay posisi tetap. Hadiah sia-sia
overscroll-behavior
sudah benar! Browser mencoba
bermanfaat tetapi
pada akhirnya situs tersebut akan
terlihat seperti bug.
Contoh - modal dengan dan tanpa overscroll-behavior: contain
:
Menonaktifkan tarik untuk memuat ulang
Menonaktifkan tindakan tarik untuk memuat ulang adalah satu baris CSS. Cukup cegah
rantai scroll di seluruh elemen yang menentukan area pandang. Dalam kebanyakan kasus, itu
<html>
atau <body>
:
body {
/* Disables pull-to-refresh but allows overscroll glow effects. */
overscroll-behavior-y: contain;
}
Dengan penambahan sederhana ini, kita memperbaiki animasi pull-to-refresh ganda di demo chatbox dan dapat sebagai gantinya, terapkan efek kustom yang menggunakan animasi pemuatan yang lebih rapi. Tujuan seluruh kotak masuk juga menjadi buram saat kotak masuk disegarkan:
Berikut adalah cuplikan dari kode lengkap:
<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>
Menonaktifkan efek glow overscroll dan rubberband
Untuk menonaktifkan efek pantulan saat mencapai batas scroll, gunakan
overscroll-behavior-y: none
:
body {
/* Disables pull-to-refresh and overscroll glow effect.
Still keeps swipe navigations. */
overscroll-behavior-y: none;
}
Demo lengkap
Menyatukan semuanya,
demo chatbox menggunakan
overscroll-behavior
untuk membuat animasi tarik untuk refresh kustom
dan menonaktifkan scroll agar tidak keluar dari widget kotak chat. Hal ini memberikan gambaran
pengalaman pengguna yang akan sulit dicapai tanpa CSS
overscroll-behavior
.