TL;DR
Właściwość CSS overscroll-behavior umożliwia deweloperom zastąpienie domyślnego zachowania przeglądarki podczas przewijania po osiągnięciu góry lub dołu treści. Przykłady zastosowań obejmują wyłączenie funkcji przeciągania w dół, aby odświeżyć na urządzeniach mobilnych, usuwanie efektów poświaty i odbicia przy przewijaniu oraz zapobieganie przewijaniu zawartości strony, gdy znajduje się ona pod oknem modalnym lub nakładką.
Tło
Granice przewijania i łańcuch przewijania
Przewijanie to jeden z najbardziej podstawowych sposobów interakcji ze stroną, ale niektóre wzorce UX mogą być trudne do obsługi ze względu na nietypowe działanie domyślne przeglądarki. Weźmy na przykład panel aplikacji z dużą liczbą elementów, które użytkownik musi przewijać. Gdy użytkownik dotrze do dołu, kontener przepełnienia przestanie się przewijać, ponieważ nie ma już żadnych treści do wyświetlenia. Innymi słowy, użytkownik osiąga „granicę przewijania”. Zobacz jednak, co się stanie, jeśli użytkownik będzie dalej przewijać. Treść za panelem zaczyna się przewijać. Przewijanie jest przejmowane przez kontener nadrzędny, czyli w tym przykładzie przez samą stronę główną.
Okazuje się, że to zachowanie nazywa się łańcuchem przewijania i jest domyślnym zachowaniem przeglądarki podczas przewijania treści. Często domyślne ustawienie jest całkiem dobre, ale czasami nie jest pożądane, a nawet może być nieoczekiwane. Niektóre aplikacje mogą zapewniać inne wrażenia, gdy użytkownik osiągnie granicę przewijania.
efekt przeciągnięcia w dół w celu odświeżenia,
Przeciąganie w dół w celu odświeżenia to intuicyjny gest spopularyzowany przez aplikacje mobilne, takie jak Facebook i Twitter. Przeciągnięcie w dół i zwolnienie strumienia treści w mediach społecznościowych tworzy nowe miejsce na załadowanie najnowszych postów. W rzeczywistości ten konkretny interfejs stał się tak popularny, że przeglądarki mobilne, takie jak Chrome na Androida, przyjęły ten sam efekt. Przesunięcie palcem w dół u góry strony odświeża całą stronę:
podczas odświeżania kanału w aplikacji PWA Twittera.
odświeża całą stronę.
W przypadku takich sytuacji jak PWA Twittera
może być warto wyłączyć natywne działanie przeciągania w dół, aby odświeżyć. Dlaczego? W tej aplikacji prawdopodobnie nie chcesz, aby użytkownik przypadkowo odświeżył stronę. Możesz też zobaczyć animację podwójnego odświeżenia. Możesz też dostosować działanie przeglądarki, aby lepiej pasowało do marki witryny. Niestety ten rodzaj dostosowywania jest trudny do zrealizowania. Deweloperzy piszą niepotrzebny kod JavaScript, dodają niepasywne detektory dotyku (które blokują przewijanie) lub umieszczają całą stronę w elemencie <div> o wymiarach 100vw/vh (aby zapobiec przepełnieniu strony). Te obejścia mają dobrze udokumentowany negatywny wpływ na wydajność przewijania.
Możemy to zrobić lepiej.
Przedstawiamy overscroll-behavior
Właściwość overscroll-behavior to nowa funkcja CSS, która kontroluje zachowanie, gdy przewijasz kontener (w tym samą stronę) poza jego granice. Możesz jej użyć, aby anulować łańcuch przewijania, wyłączyć lub dostosować działanie przeciągania w celu odświeżenia, wyłączyć efekty gumki w iOS (gdy Safari wdroży overscroll-behavior) i nie tylko.
Najlepsze jest to, że używanie overscroll-behavior nie wpływa negatywnie na wydajność strony, w przeciwieństwie do sztuczek wspomnianych we wstępie.
Właściwość może mieć 3 wartości:
- auto – domyślna. Przewijanie, które rozpoczyna się na elemencie, może zostać przeniesione na elementy nadrzędne.
- contain – zapobiega łańcuchowemu przewijaniu. Przewijanie nie jest przekazywane do elementów nadrzędnych, ale wyświetlane są efekty lokalne w węźle. Na przykład efekt overscroll na Androidzie lub efekt gumki na iOS, który powiadamia użytkownika, gdy osiągnie granicę przewijania. Uwaga: użycie
overscroll-behavior: containw elemenciehtmlzapobiega działaniom nawigacyjnym związanym z przewijaniem poza obszar. - none – działa tak samo jak
contain, ale zapobiega też efektom przewijania poza zakres w samym węźle (np. poświata przewijania poza zakres na Androidzie lub efekt gumki na iOS).
Przyjrzyjmy się kilku przykładom, aby zobaczyć, jak używać overscroll-behavior.
Zapobieganie przewijaniu poza element o stałej pozycji
Scenariusz z oknem czatu
Powiedzmy, że masz okno czatu o stałej pozycji u dołu strony. Z założenia okno czatu jest samodzielnym komponentem i przewija się niezależnie od treści, które się za nim znajdują. Jednak ze względu na łańcuch przewijania dokument zaczyna się przewijać, gdy tylko użytkownik dotrze do ostatniej wiadomości w historii czatu.
W przypadku tej aplikacji bardziej odpowiednie jest, aby przewijanie, które zaczyna się w oknie czatu, pozostawało w czacie. Możemy to zrobić, dodając overscroll-behavior: contain do elementu, który zawiera wiadomości na czacie:
#chat .msgs {
overflow: auto;
overscroll-behavior: contain;
height: 300px;
}
Zasadniczo tworzymy logiczną separację między kontekstem przewijania okna czatu a stroną główną. W efekcie strona główna pozostaje na swoim miejscu, gdy użytkownik dotrze do góry lub dołu historii czatu. Przewijanie, które zaczyna się w oknie czatu, nie jest przenoszone na zewnątrz.
Scenariusz nakładki na stronę
Inną odmianą scenariusza „underscroll” jest sytuacja, w której widzisz treść przewijaną za nakładką o stałej pozycji. To oczywiste, że overscroll-behavior zasługuje na nagrodę. Przeglądarka próbuje pomóc, ale w efekcie strona wygląda, jakby zawierała błędy.
Przykład – okno modalne z atrybutem overscroll-behavior: contain i bez niego:
Wyłączanie funkcji przeciągania w dół, aby odświeżyć
Wyłączenie działania „przeciągnij, aby odświeżyć” to jedna linijka kodu CSS. Wystarczy zapobiec łańcuchowemu przewijaniu
w całym elemencie definiującym widoczny obszar. W większości przypadków jest to <html> lub <body>:
body {
/* Disables pull-to-refresh but allows overscroll glow effects. */
overscroll-behavior-y: contain;
}
Dzięki temu prostemu dodatkowi naprawiamy podwójne animacje przeciągania w dół, aby odświeżyć, w wersji demonstracyjnej okna czatu, i możemy zamiast tego wdrożyć efekt niestandardowy, który używa bardziej przejrzystej animacji ładowania. Podczas odświeżania skrzynki odbiorczej cała jej zawartość jest rozmyta:
Oto fragment pełnego kodu:
<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>
Wyłączanie efektów poświaty i gumki przy przewijaniu poza krawędź
Aby wyłączyć efekt odbicia po osiągnięciu granicy przewijania, użyj overscroll-behavior-y: none:
body {
/* Disables pull-to-refresh and overscroll glow effect.
Still keeps swipe navigations. */
overscroll-behavior-y: none;
}
Pełna wersja demonstracyjna
W pełnej wersji demonstracyjnej okna czatu użyto overscroll-behavior do utworzenia niestandardowej animacji przeciągania w dół, aby odświeżyć, i wyłączenia przewijania poza widżet okna czatu. Zapewnia to optymalne wrażenia użytkownika, które trudno byłoby osiągnąć bez CSS overscroll-behavior.