Przejmij kontrolę nad przewijaniem – dostosuj efekty przeciągnięcia, aby odświeżyć lub przepełnienia

TL;DR

Właściwość CSS overscroll-behavior pozwala programistom zastępować domyślne zachowanie przeglądarki, gdy użytkownik dotrze do górnej lub dolnej części treści. Można na przykład wyłączyć funkcję „przeciągnij, by odświeżyć” na urządzeniach mobilnych, usunąć efekty poświaty i efektów gumowania pasów oraz zapobiegać przewijaniu zawartości strony, gdy znajduje się pod modalną lub nakładką.

Wprowadzenie

Obramowanie i przewijanie łańcuchów

Przewijanie łańcuszków w Chrome na Androida.

Przewijanie to jeden z najważniejszych sposobów interakcji ze stroną. Jednak pamiętaj, że z niektórymi wzorcami UX może być trudno uporać się z nietypowymi, domyślnymi ustawieniami przeglądarki. Przeanalizujmy panel aplikacji z dużą liczbą elementów, które użytkownik będzie musiał przewinąć. Po dotarciu do dołu kontenera kontener nadmiarowy przestaje się przewijać, ponieważ nie ma więcej treści, które można wykorzystać. Oznacza to, że użytkownik osiąga „granicę przewijania”. Zwróć jednak uwagę na to, co się stanie, jeśli użytkownik będzie kontynuować przewijanie. Zawartość za panelem zacznie się przewijać. Przewijanie jest przejmowane przez kontener nadrzędny, a w przykładzie samą stronę główną.

Określa to działanie jako łańcuch przewijania. Jest to domyślne zachowanie przeglądarki podczas przewijania treści. Ustawienia domyślne często są fajne, ale czasem nie są pożądane ani nieoczekiwane. Niektóre aplikacje mogą oferować różne funkcje, gdy użytkownik otworzy granicę przewijania.

Efekt „przeciągnij, by odświeżyć”

„Przeciągnij, by odświeżyć” to intuicyjny gest popularny w aplikacjach mobilnych, takich jak Facebook czy Twitter. Przesunięcie kanału w dół i opublikowanie nowego kanału społecznościowego tworzy nowe miejsce, w którym wczytywane są najnowsze posty. W rzeczywistości interfejs ten stał się tak popularny, że w przeglądarkach mobilnych, takich jak Chrome na Androidzie, udało się zastosować ten sam efekt. Przesunięcie palcem w dół u góry strony odświeża całą stronę:

Niestandardowa funkcja odświeżania na Twitterze
podczas odświeżania kanału w PWA.
Natywne działanie „przeciągnij, by odświeżyć” w Chrome na Androida
odświeża całą stronę.

W sytuacjach takich jak PWA na Twitterze warto wyłączyć natywne działanie „przeciągnij, by odświeżyć”. Dlaczego? Zapewne w niej nie chcesz, aby użytkownik przypadkowo odświeżył stronę. Animację można też podwójnie odświeżyć. Albo lepiej dostosować działanie przeglądarki, dopasowując je do marki witryny. Niestety takie dostosowanie jest dość skomplikowane. Programiści piszą w nim niepotrzebny kod JavaScript, dodają niepasywne detektory dotykowe (blokujące przewijanie) lub pozostawiają całą stronę w poziomie 100vw/vh<div> (aby zapobiec jej przepełnieniu). Te rozwiązania mają dobrze udokumentowany negatywny wpływ na wydajność przewijania.

Możemy robić lepiej!

Przedstawiamy overscroll-behavior

Usługa overscroll-behavior to nowa funkcja CSS, która kontroluje zachowanie, gdy użytkownik przewinie kontener (w tym samą stronę) po najechaniu kursorem. Możesz za jego pomocą anulować łańcuch przewijania, wyłączyć lub dostosować działanie „przeciągnij do odświeżania”, wyłączyć efekty gumowania paska w iOS (gdy Safari implementuje overscroll-behavior) i wykonywać inne działania. Korzystanie z overscroll-behavior nie wpływa negatywnie na wydajność strony, takie jak zmiany omówione we wstępie.

Właściwość może mieć 3 możliwe wartości:

  1. auto – wartość domyślna. Przewinięcia pochodzące z danego elementu mogą być propagowane do elementów nadrzędnych.
  2. contain – zapobiega tworzeniu łańcuchów przewijania. Przewinięcia nie są rozpowszechniane do elementów nadrzędnych, ale widoczne są efekty lokalne w węźle. Dotyczy to na przykład efektu poświaty nadmiernie przewijania na Androidzie lub efektu pasma gumowego na iOS, który powiadamia użytkownika o osiągnięciu granicy przewijania. Uwaga: użycie overscroll-behavior: contain w elemencie html uniemożliwia wykonywanie działań związanych z nadmiernym przewijaniem.
  3. none (brak) – tak samo jak contain, ale zapobiega także nadmiernym przewijaniu w obrębie samego węzła (np. podświetlenie w Androidzie lub gumowe pasy na urządzeniach z iOS).

Przyjrzyjmy się kilku przykładom, aby dowiedzieć się, jak używać elementu overscroll-behavior.

Zapobiegaj zmianie znaczenia elementów przewijania o stałej pozycji

Scenariusz rozmowy z czatem

Treści pod oknem czatu też przewijają się :(

Rozważmy stałe okno czatu, które znajduje się u dołu strony. Pole czatu jest autonomicznym elementem i przewija się niezależnie od zawartości, która się za nim znajduje. Jednak z powodu łańcucha przewijania dokument zaczyna go przewijać, gdy tylko użytkownik znajdzie ostatnią wiadomość w historii czatu.

W przypadku tej aplikacji lepiej, aby przewijane treści pochodzące z okna czatu pozostawały na czacie. Aby to zrobić, dodaj atrybut overscroll-behavior: contain do elementu, który zawiera wiadomości czatu:

#chat .msgs {
  overflow: auto;
  overscroll-behavior: contain;
  height: 300px;
}

Zasadniczo tworzymy logiczne odseparowanie kontekstu przewijanego pola czatu od strony głównej. Dzięki temu strona główna pozostaje dostępna, gdy użytkownik dotrze do górnej lub dolnej części historii czatu. Przewinięcia, które rozpoczynały się w oknie czatu, nie są rozpowszechniane.

Scenariusz nakładania się strony

Inną odmianą scenariusza „pod przewijaniem” jest sytuacja, w której treści przewijają się za nakładką o stałej pozycji. Nagroda overscroll-behavior jest w zasięgu ręki! Przeglądarka stara się pomagać, ale w efekcie strona wygląda dziwnie.

Przykład – modalny z parametrem overscroll-behavior: contain i bez niego:

Przed: zawartość strony przewija się pod nakładką.
Po: zawartość strony nie przewija się pod nakładką.

Wyłączam funkcję „przeciągnij, by odświeżyć”

Wyłączenie działania „przeciągnij, by odświeżyć” to pojedynczy wiersz kodu CSS. Po prostu nie zezwalaj na przewijanie łańcuchami całego elementu definiującego 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;
}

Ten prosty dodatek poprawia problemy z podwójnymi animacjami „przeciągnij, aby odświeżyć” w wersji demonstracyjnej okna czatu i może zamiast tego zastosować niestandardowy efekt, który korzysta z ładniejszej animacji wczytywania. Cała skrzynka odbiorcza też się rozmywa, gdy jest odświeżana:

Przed
Po

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łączam nadmierną poświatę i efekty gumowania

Aby wyłączyć efekt odbicia po dotarciu do granicy przewijania, użyj polecenia overscroll-behavior-y: none:

body {
  /* Disables pull-to-refresh and overscroll glow effect.
     Still keeps swipe navigations. */
  overscroll-behavior-y: none;
}
Przed: kliknięcie granicy przewijania powoduje pojawienie się poświaty.
Po: poświata wyłączona.

Pełna wersja demonstracyjna

Po połączeniu w całości prezentacja okna czatu wykorzystujeoverscroll-behaviordo tworzenia niestandardowej animacji po naciśnięciu i odświeżaniu i wyłącza przewijanie zawartości pola czatu. Pozwala to uzyskać optymalne wrażenia użytkownika, które nie byłoby trudno osiągnąć bez korzystania z CSS overscroll-behavior.

Wyświetl wersję demonstracyjną | Źródło