Kendalikan scroll Anda - menyesuaikan efek pull-to-refresh dan overflow

TL;DR

Properti CSS overscroll-behavior memungkinkan developer mengganti perilaku scroll tambahan default browser saat mencapai bagian atas/bawah konten. Kasus penggunaan mencakup penonaktifan fitur tarik untuk memuat ulang di perangkat seluler, penghapusan efek glow dan rubberbanding overscroll, serta pencegahan konten halaman agar tidak di-scroll saat berada di bawah modal/overlay.

Latar belakang

Batas scroll dan perantaian scroll

Perangkaian scroll di Chrome Android.

Men-scroll adalah salah satu cara paling mendasar untuk berinteraksi dengan halaman, tetapi pola UX tertentu bisa jadi sulit ditangani karena perilaku default browser yang unik. Sebagai contoh, ambil panel daftar 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 dapat digunakan. Dengan kata lain, pengguna mencapai "batas scroll". Namun, 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 perantaian scroll; perilaku default browser saat men-scroll konten. Sering kali setelan defaultnya cukup bagus, tetapi 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 memuat ulang adalah gestur intuitif yang dipopulerkan oleh aplikasi seluler seperti Facebook dan Twitter. Menarik ke bawah feed media sosial dan melepaskannya akan menciptakan ruang baru untuk memuat postingan yang lebih baru. 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 memuat ulang seluruh halaman:

Tarik untuk memuat ulang kustom Twitter
saat memuat ulang feed di PWA mereka.
Tindakan tarik untuk memuat ulang native Chrome Android
memuat ulang seluruh halaman.

Untuk situasi seperti PWA Twitter, mungkin sebaiknya nonaktifkan tindakan tarik untuk memuat ulang native. Mengapa? Di aplikasi ini, Anda mungkin tidak ingin pengguna memuat ulang halaman secara tidak sengaja. Ada juga potensi untuk melihat animasi refresh ganda. Atau, mungkin akan lebih baik untuk menyesuaikan tindakan browser, sehingga lebih selaras dengan branding situs. Sayangnya, jenis penyesuaian ini sulit dilakukan. Developer akhirnya menulis JavaScript yang tidak perlu, menambahkan pemroses sentuh non-pasif (yang memblokir scroll), atau menempelkan seluruh halaman dalam <div> 100vw/vh (untuk mencegah halaman meluap). Solusi ini memiliki efek negatif yang terdokumentasi dengan baik pada 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 perantaian 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 akan berdampak buruk pada performa halaman seperti peretasan yang disebutkan dalam pengantar.

Properti ini memiliki tiga kemungkinan nilai:

  1. auto - Default. Scroll yang berasal dari elemen dapat diterapkan ke elemen ancestor.
  2. contain - mencegah perantaian 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 elemen html akan mencegah tindakan navigasi overscroll.
  3. none - sama seperti contain, tetapi juga mencegah efek overscroll dalam node itu sendiri (misalnya, glow overscroll Android atau rubberbanding iOS).

Mari kita pelajari beberapa contoh untuk melihat cara menggunakan overscroll-behavior.

Mencegah scroll keluar dari elemen posisi yang tetap

Skenario kotak chat

Konten di bawah jendela chat juga di-scroll :(

Pertimbangkan kotak chat dengan posisi tetap yang berada di bagian bawah halaman. Tujuannya adalah agar kotak chat menjadi komponen mandiri dan dapat di-scroll secara terpisah dari konten di belakangnya. Namun, karena perantaian scroll, dokumen mulai di-scroll segera setelah pengguna mencapai pesan terakhir dalam histori chat.

Untuk aplikasi ini, lebih tepat jika scroll yang berasal dari dalam kotak chat tetap berada dalam chat. Kita dapat melakukannya 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 kotak chat dan halaman utama. Hasil akhirnya adalah halaman utama tetap berada di tempatnya saat pengguna mencapai bagian atas/bawah histori chat. Scroll yang dimulai di kotak chat tidak akan menyebar ke luar.

Skenario overlay halaman

Variasi lain dari skenario "underscroll" adalah saat Anda melihat konten di-scroll di balik overlay posisi tetap. Tanda yang jelas overscroll-behavior sudah sesuai urutan. Browser mencoba membantu, tetapi malah membuat situs terlihat bermasalah.

Contoh - modal dengan dan tanpa overscroll-behavior: contain:

Sebelum: konten halaman di-scroll di bawah overlay.
Setelah: konten halaman tidak di-scroll di bawah overlay.

Menonaktifkan tarik untuk memuat ulang

Menonaktifkan tindakan tarik untuk memuat ulang adalah satu baris CSS. Cukup cegah perantaian scroll di seluruh elemen yang menentukan area pandang. Dalam sebagian besar kasus, itu adalah <html> atau <body>:

body {
  /* Disables pull-to-refresh but allows overscroll glow effects. */
  overscroll-behavior-y: contain;
}

Dengan penambahan sederhana ini, kita memperbaiki animasi tarik untuk memuat ulang ganda di demo kotak chat dan dapat menerapkan efek kustom yang menggunakan animasi pemuatan yang lebih rapi. Seluruh kotak masuk juga akan diburamkan saat kotak masuk dimuat ulang:

Sebelum
Setelah

Berikut cuplikan kode lengkapnya:

<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="refre>she<r"
  div class=&qu><ot;l>oad<ing-bar"/div
  div>< cla>ss=<"loading-bar"></div>
  <div class="loading><-bar>&<quot>;/<div
  div class=&q><uot;loading><-bar&quo>t;</div
/>div

section id="inbox"!-- msgs --/section

script
  let _startY;
  const inbox = document.querySel>ector('#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.class<List.co>ntains('refreshing')) {
      // refresh inbox.
    }
  }, {passive: true});
/script

Menonaktifkan efek glow dan rubberbanding overscroll

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;
}
Sebelum: mencapai batas scroll akan menampilkan cahaya.
Setelah: cahaya dinonaktifkan.

Demo lengkap

Secara keseluruhan, demo chatbox lengkap menggunakan overscroll-behavior untuk membuat animasi tarik untuk memuat ulang kustom dan menonaktifkan scroll agar tidak keluar dari widget chatbox. Hal ini memberikan pengalaman pengguna yang optimal yang akan sulit dicapai tanpa CSS overscroll-behavior.

Lihat demo | Sumber