Dobrze kontrolowane przewijanie za pomocą funkcji CSS Scroll Snap

Aby zapewnić dobrą kontrolę nad przewijaniem, deklaruj pozycje przyciągania przewijania.

Robert Flack
Robert Flack
Majid Valipour
Majid Valipour

Funkcja przyciągania przewijania w CSS pozwala programistom stron internetowych na deklarowanie pozycji przeciągania, by dobrze kontrolować przewijanie. Najczęściej używane są artykuły podzielone na strony i karuzele obrazów. CSS Scroll Snap zapewnia łatwy w użyciu i spójny interfejs API do tworzenia tych popularnych wzorców UX.

Wprowadzenie

Przyciąganie na przewijanie

Przewijanie to popularny i naturalny sposób interakcji z treściami w internecie. Jest to natywny sposób oferowania tej platformy dostępu do większej ilości informacji, niż jest to widoczne na ekranie. Szczególnie ważne w przypadku platform mobilnych z ograniczoną ilością miejsca na ekranie. Nic więc dziwnego, że autorzy stron internetowych coraz częściej wolą porządkować treści na przewijanych, płaskich listach, a nie na głębokich hierarchii.

Główną wadą przewijania jest brak precyzji. Rzadko zdarza się, że przewijanie zostaje wyrównane do akapitu lub zdania. Jest to jeszcze bardziej widoczne w przypadku treści podzielonych na strony lub podzielonych na strony ze znaczącymi granicami, gdy przewija się do końca strony lub obrazu i pozostaje częściowo widoczne. W takich przypadkach używa się dobrze kontrolowanego przewijania.

Programiści stron internetowych od dawna polegają na rozwiązaniach opartych na języku JavaScript, które pomogły rozwiązać ten problem w zakresie kontrolowania przewijania. Jednak rozwiązania oparte na języku JavaScript nie zapewniają rozwiązania z pełną wiernością z powodu braku podstawowych elementów do dostosowywania przewijania lub dostępu do przewijania skomponowanego. CSS Scroll Snap to szybkie rozwiązanie o wysokiej jakości i łatwym w użyciu, które działa spójnie w różnych przeglądarkach.

Funkcja CSS Scroll Snap umożliwia autorom stron internetowych oznaczanie kontener przewijania za pomocą granic w celu zakończenia operacji przewijania. Przeglądarki wybierają najbardziej odpowiednią pozycję końcową w zależności od specyfiki operacji przewijania, układu i widoczności kontenera przewijania oraz szczegółów pozycji przyciągania, a potem płynnie animują obraz w tym miejscu. Wracając do wcześniejszego przykładu: gdy użytkownik zakończy przewijanie karuzeli, jej widoczny obraz wskoczy na miejsce. JavaScript nie wymaga żadnych korekt związanych z przewijaniem.

Przykład użycia przyciągania przewijanego przez CSS z karuzelą obrazów.
Przykład użycia funkcji przyciągania przewijania CSS z karuzelą obrazów. W tym przypadku przyciąganie przewijania sprawia, że na końcu przewijania obrazu środek w poziomie i w poziomie znajduje się względem środka kontenera przewijania.

CSS – przewijanie

Przyciąganie to polega na dostosowywaniu przesunięcia przewijania kontenera przewijania w taki sposób, by po zakończeniu przewijania znajdowały się w wybranej pozycji przyciągania.

W kontenerze przewijania można włączyć przyciąganie przewijania za pomocą właściwości scroll-snap-type. To informuje przeglądarkę, że powinna rozważyć przyciąganie tego kontenera przewijania do pozycji przyciągania wygenerowanych przez elementy podrzędne. scroll-snap-type określa oś, na której następuje przewijanie: x, y lub both, oraz rygorystyczność przyciągania: mandatory, proximity. Więcej na ten temat później.

Położenie przyciągania można określić, deklarując żądane wyrównanie elementu. Ta pozycja to przesunięcie przewijania, przy którym najbliższy przodek przewijany i element są wyrównane zgodnie z ustawieniami danej osi. Na każdej osi można wyrównać te elementy: start, end oraz center.

Wyrównanie start oznacza, że krawędź początkowa snapportu kontenera przewijania powinna być przesuwana względem krawędzi początkowej obszaru przyciągania elementu. Wyrównanie end i center oznacza, że końcowa lub środek snapportu kontenera przewijania powinna być wyrównana względem krawędzi lub środka obszaru przyciągania elementu.

Przykład różnych wyrównań na poziomej osi przewijania.

Poniższe przykłady pokazują, jak korzystać z tych pojęć.

Typowym przypadkiem użycia przyciągania do przewijania jest karuzela obrazów. Aby np. utworzyć poziomą karuzelę obrazów, która przyciąga do każdego obrazu, gdy przewijasz, możemy określić w kontenerze przewijania element scroll-snap-type na osi poziomej. Ustaw wartość każdego obrazu na scroll-snap-align: center, aby zapewnić, że przyciąganie wyśrodkowuje obraz w karuzeli.

#gallery {
  scroll-snap-type: x mandatory;
  overflow-x: scroll;
  display: flex;
}

#gallery img {
   scroll-snap-align: center;
}
<div id="gallery">
  <img src="cat.jpg">
  <img src="dog.jpg">
  <img src="another_cute_animal.jpg">
</div>

Pozycje przyciągania są powiązane z elementem, dlatego algorytm przyciągania może decydować o tym, kiedy i w jaki sposób się przyciąga, biorąc pod uwagę rozmiar elementu i kontenera przewijania. Weźmy pod uwagę przykład sytuacji, w której 1 obraz jest większy od karuzeli. Algorytm naiwnego przyciągania może uniemożliwiać użytkownikowi przesuwanie w celu wyświetlenia całego obrazu. Specyfikacja wymaga jednak implementacji, które wykryją taki przypadek i umożliwią użytkownikowi swobodne przewijanie treści w obrębie obrazu (i przyciąganie do krawędzi).

Wyświetl prezentację | Źródło

Przykład: przeglądana strona produktu

Innym typowym przypadkiem, dla którego warto korzystać z przyciągania na przewijanie, są strony z wieloma sekcjami logicznymi, które można przewijać w pionie, np. typową stronę produktu. W takich przypadkach zasada scroll-snap-type: y proximity; jest bardziej naturalna. Nie przeszkadza w przewinięciu przez użytkownika do środka danej sekcji, ale gdy użytkownik przewinie wystarczająco blisko, przyciąga uwagę i przyciąga uwagę.

Jak to osiągnąć:

article {
  scroll-snap-type: y proximity;
  /* Reserve space for header plus some extra space for sneak peeking. */
  scroll-padding-top: 15vh;
  overflow-y: scroll;
}
section {
  /* Snap align start. */
  scroll-snap-align: start;
}
header {
  position: fixed;
  height: 10vh;
}
<article>
  <header> Header </header>
  <section> Section One </section>
  <section> Section Two </section>
  <section> Section Three </section>
</article>

Dopełnienie i margines przewijania

Strona produktu ma stały nagłówek górny. Projekt wymagał też, aby część górnej sekcji pozostawała widoczna po przyciągnięciu kontenera przewijania, aby użytkownicy wiedzieli o powyższej zawartości.

scroll-padding to nowa właściwość CSS, która pozwala dostosować widoczny obszar kontenera przewijania (Snapport), która służy do obliczania wyrównania przyciągania przewijania. Właściwość ta określa wcięcie względem pola dopełnienia kontenera przewijania. W naszym przykładzie na górze zostało dodane dodatkowe wcięcie 15vh, które informuje przeglądarkę, że przy przyciąganiu będzie uwzględniać niższą pozycję (15vh poniżej górnej krawędzi kontenera przewijania), która jest jego pionową krawędzią początkową. Podczas przyciągania krawędź początkowa elementu przyciągającego zostanie przesuwana w tej nowej pozycji i zostaje nad nią pusta.

Właściwość scroll-margin określa wartość rozpoczęcia używaną do dostosowania efektywnego pola przyciągającego, podobnie jak działa scroll-padding w kontenerze przewijania.

Jak widzisz, te 2 usługi nie zawierają słowa „snap”. Jest to zamierzone, ponieważ modyfikują one pole pod kątem wszystkich odpowiednich operacji przewijania, a nie tylko przewijanie. Chrome uwzględnia je np. podczas obliczania rozmiaru strony na potrzeby operacji przewijania stronicowania takich jak PageDown i PageUp, a także podczas obliczania ilości przewijania w ramach operacji Element.scrollIntoView().

Wyświetl prezentację | Źródło

Interakcja z innymi interfejsami API przewijania

Interfejs DOM Scrolling API

Przyciąganie przewijania odbywa się po wszystkich operacjach przewijania, w tym tych zainicjowanych przez skrypt. Gdy używasz interfejsów API takich jak Element.scrollTo, przeglądarka obliczy zamierzone miejsce przewijania podczas operacji, a potem zastosuje odpowiednią logikę przyciągania, aby znaleźć ostateczną lokalizację. Dzięki temu skrypt użytkownika nie musi wykonywać żadnych ręcznych obliczeń związanych z przyciąganiem.

Płynne przewijanie

Płynne przewijanie steruje działaniem operacji automatycznego przewijania, a przyciąganie określa miejsce docelowe. Kontrolują one ortogonalne aspekty przewijania, więc można je stosować razem i uzupełniać.

Zachowanie nadmiernego przewijania

Interfejs OverscrollBehavior API określa sposób wiązania przewijania między wieloma elementami i nie ma na niego wpływu przyciąganie uwagi.

Zastrzeżenia i sprawdzone metody

Unikaj używania obowiązkowego przyciągania, gdy elementy docelowe znajdują się w dużej odległości od siebie. W rezultacie treści między poszczególnymi pozycjami mogą stać się niedostępne.

W wielu przypadkach przyciąganie przewijania można dodać jako ulepszenie bez konieczności wykrywania funkcji. W razie potrzeby użyj @supports lub CSS.supports, aby wykryć obsługę przewijania CSS Scroll Snap. Unikaj używania atrybutu scroll-snap-type, który występuje też w wycofanej specyfikacji.

Wykrywanie funkcji w CSS

@supports (scroll-snap-align: start) {
  article {
    scroll-snap-type: y proximity;
    scroll-padding-top: 15vh;
    overflow-y: scroll;
  }
}

Wykrywanie funkcji w kodzie JavaScript

if (CSS.supports('scroll-snap-align: start')) {
  // use css scroll snap
} else {
  // use fallback
}

Nie zakładaj, że interfejsy API do automatycznego przewijania, takie jak Element.scrollTo, zawsze kończą się na żądanym czasie przewijania. Przyciąganie podczas przewijania może dostosować przesunięcie przewijania po zakończeniu automatycznego przewijania. Zauważ, że nie było to dobre założenie jeszcze przed przyciąganiem przewijania, ponieważ przewijanie mogło zostać zakłócone z innych powodów, ale zwłaszcza w przypadku przyciągania przewijania.

Praca w przyszłości

Tematyką niedawnej ankiety przeprowadzonej przez zespół Chrome była funkcja przewijania. Wyniki ankiety wskazują kilka obszarów, które wymagają podjęcia dodatkowych działań, aby zmniejszyć lukę między bibliotekami wtyczek a kodami CSS. Najbliższe prace będą się koncentrować na scroll-snap, w tym:

  1. Dostępność i zgodność interfejsu API w różnych przeglądarkach.
  2. Wykorzystaj nowe interfejsy API CSS, takie jak scroll-start.
  3. Popracuj nad nowymi zdarzeniami JS takimi jak snapChanged().