Dobrze kontrolowane przewijanie za pomocą funkcji CSS Scroll Snap

Aby zapewnić dobrze kontrolowane przewijanie, określ pozycje zatrzymywania przewijania.

Robert Flack
Robert Flack
Majid Valipour
Majid Valipour

Funkcja CSS Scroll Snap pozwala deweloperom tworzyć dobrze kontrolowane przewijanie, deklarując pozycje zatrzymywania przewijania. Przykładami tego są artykuły podzielone na strony i karuzele obrazów. CSS Scroll Snap to łatwy w użyciu i spójny interfejs API do tworzenia tych popularnych wzorców UX.

Tło

Dlaczego warto stosować przycinanie przewijania

Przewijanie jest popularnym i naturalnym sposobem na interakcję z treściami w internecie. Jest to natywny sposób udostępniania większej ilości informacji niż widocznych na ekranie w danym momencie. Jest szczególnie przydatny na platformach mobilnych z ograniczoną przestrzenią ekranu. Nic więc dziwnego, że autorzy stron internetowych coraz częściej preferują organizację treści w formie przewijanych list, a nie rozbudowanych hierarchii.

Główną wadą przewijania jest brak precyzji. Rzadko zdarza się, aby koniec przewijania był wyrównany do akapitu lub zdania. Jest to jeszcze bardziej widoczne w przypadku treści podzielonych na strony lub treści uporządkowanej w kolumny, gdy przewijanie kończy się w połowie strony lub obrazu, pozostawiając go częściowo widocznym. W tych przypadkach dobrze kontrolowane przewijanie jest bardzo przydatne.

Programiści stron internetowych od dawna polegają na rozwiązaniach opartych na JavaScriptie, aby kontrolować przewijanie i w ten sposób zniwelować tę wadę. Rozwiązania oparte na JavaScript nie zapewniają jednak pełnej zgodności ze standardami ze względu na brak prymitywów dostosowywania do przewijania lub dostępu do złożonego przewijania. CSS Scroll Snap zapewnia szybkie, niezawodne i łatwe w użyciu rozwiązanie, które działa spójnie w różnych przeglądarkach.

CSS Scroll Snap pozwala autorom stron internetowych oznaczać każdy kontener przewijania za pomocą granic, które określają, gdzie ma się zakończyć przewijanie. Następnie przeglądarki wybierają najbardziej odpowiednią pozycję końcową w zależności od szczegółów operacji przewijania, układu i widoczności kontenera przewijania oraz szczegółów pozycji zaczepienia, a następnie płynnie animują do niej. Wróćmy do naszego wcześniejszego przykładu. Gdy użytkownik przestanie przewijać karuzel, widoczny obraz zostanie zablokowany na miejscu. Nie trzeba wprowadzać żadnych korekt przewijania za pomocą JavaScript.

Przykład użycia css scroll snap z karuzelą obrazów.
Przykład użycia css scroll snap z karuzelą obrazów. Tutaj blokowanie przewijania zapewnia, że na końcu przewijania obraz jest wyrównany poziomo z poziomym środkiem kontenera przewijania.

CSS Scroll Snap

Przyciąganie podczas przewijania to dostosowywanie przesunięcia kontenera przewijania do preferowanej pozycji przyciągania po zakończeniu operacji przewijania.

Aby włączyć łączenie przewijania, użyj właściwości scroll-snap-type. Informuje przeglądarkę, że powinna rozważyć przyciąganie tego kontenera do pozycji przyciągania utworzonych przez jego potomków. scroll-snap-typeokreśla oś, po której następuje przewijanie: x, y lub both, oraz stopień dokładności przy przyciąganiu: mandatory, proximity. Więcej informacji na ten temat znajdziesz w następnych częściach.

Położenie elementu po przybliżeniu można uzyskać, deklarując żądane wyrównanie. Ta pozycja to przesunięcie przewijania, przy którym kontener przewijania najbliższego przodka i element są wyrównane zgodnie z ustawieniami dla danej osi. Na każdej osi możliwe są te wyrównania: start, end, center.

Wyrównanie start oznacza, że krawędź początkowa punktu zaczepienia kontenera przewijania powinna być wyrównana z krawędzią początkową obszaru zaczepienia elementu. Podobnie wyrównania endcenter oznaczają, że krawędź lub środek krawędzi uchwytu kontenera do przewijania powinien być wyrównany z krawędzią lub środkiem obszaru przyciągania elementu.

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

Poniższe przykłady pokazują, jak stosować te koncepcje.

Typowym zastosowaniem przewijania z podświetleniem jest karuzela zdjęć. Na przykład, aby utworzyć poziomą karuzelkę obrazów, która będzie się automatycznie dostosowywać do każdego obrazu podczas przewijania, możesz określić, że kontener przewijania ma mieć obowiązkową wartość scroll-snap-type na osi poziomej. Aby upewnić się, że obraz będzie wyśrodkowany w karuzeli, ustaw dla każdego obrazu wartość scroll-snap-align: center.

#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>

Ponieważ pozycje przyciągania są powiązane z elementem, algorytm przyciągania może inteligentnie określać, kiedy i jak ma przyciągać dany element oraz kontener do przewijania. Rozważmy na przykład przypadek, gdy jedno zdjęcie jest większe niż karuzela. Prosty algorytm przyciągania może uniemożliwić użytkownikowi przesuwanie obrazu w celu obejrzenia go w pełni. Jednak specyfikacja wymaga, aby implementacje wykrywały ten przypadek i umożliwiały użytkownikowi swobodne przewijanie obrazu tylko przy jego krawędziach.

Wyświetl demo | Źródło

Przykład: strona produktu z przebiegiem

Innym typowym przypadkiem, w którym przydaje się przewijanie skrótowe, są strony z kilkoma logicznie uporządkowanymi sekcjami, np. typowa strona produktu. scroll-snap-type: y proximity; jest bardziej odpowiedni w przypadkach takich jak ten. Nie przeszkadza, gdy użytkownik przewija stronę do połowy, ale przyciąga uwagę do nowej sekcji, gdy użytkownik przewinie do niej.

Oto jak to zrobić:

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 u góry. Projekt wymagał też, aby część górna była widoczna, gdy kontener przewijania jest zablokowany, aby użytkownicy mieli wskazówkę dotyczącą treści powyżej.

Właściwość scroll-padding to nowa właściwość CSS, która może służyć do dostosowywania skutecznego obszaru widocznego kontenera przewijania (czyli portu zapinania) używanego podczas obliczania wyrównania zapinania przewijania. Właściwość ta określa wcięcie względem pola wypełnienia kontenera przewijania. W naszym przykładzie dodano dodatkowy element 15vh u góry, który instruuje przeglądarkę, aby wzięła pod uwagę niższą pozycję, 15vh poniżej górnej krawędzi kontenera przewijania, jako pionową krawędź początkową do przyciągania. Podczas łączenia krawędź początkowa elementu docelowego zostanie dopasowana do nowej pozycji, pozostawiając wolną przestrzeń powyżej.

Właściwość scroll-margin definiuje odstęp początkowy używany do dostosowywania skutecznego obszaru docelowego docelowego punktu zaznaczenia w sposób podobny do działania właściwości scroll-padding w przypadku ruchomego kontenera przewijania.

Zauważysz pewnie, że te 2 właściwości nie zawierają słowa „snap”. Jest to celowe działanie, ponieważ te elementy faktycznie modyfikują pole we wszystkich odpowiednich operacjach przewijania, a nie tylko przyklejają przewijanie. Na przykład Chrome uwzględnia je podczas obliczania rozmiaru strony w przypadku operacji przewijania stron, takich jak PageDown i PageUp, a także podczas obliczania ilości przewinięcia w przypadku operacji Element.scrollIntoView().

Wyświetl demo | Źródło

Interakcje z innymi interfejsami API przewijania

DOM Scrolling API

Przycinanie przewijania następuje po wszystkich operacjach przewijania, w tym tych rozpoczętych przez skrypt. Gdy używasz interfejsów API, takich jak Element.scrollTo, przeglądarka oblicza docelową pozycję przewijania operacji, a następnie stosuje odpowiednią logikę wyrównywania, aby znaleźć ostateczną pozycję wyrównania. Dlatego nie ma potrzeby, aby skrypt użytkownika wykonywał ręczne obliczenia dotyczące zaklinowania.

płynne przewijanie,

Płynne przewijanie kontroluje działanie automatycznej operacji przewijania, a dostosowanie do przewijania określa jej miejsce docelowe. Ponieważ kontrolują one ortogonalne aspekty przewijania, mogą być używane razem i uzupełniać się nawzajem.

Działanie overscroll

Interfejs API zachowania przewijania steruje tym, jak przewijanie jest łańcuchowane między wieloma elementami, i nie jest zależne od zatrzymywania przewijania.

Ostrzeżenia i sprawdzone metody

Unikaj stosowania obowiązkowego łapania, gdy elementy docelowe są od siebie bardzo oddalone. Może to spowodować, że treści między pozycjami przyciągania będą niedostępne.

W wielu przypadkach możesz dodać funkcję przewijania z automatycznym dopasowaniem bez konieczności wykrywania funkcji. W razie potrzeby użyj @supports lub CSS.supports, aby wykryć obsługę funkcji CSS Scroll Snap. Unikaj używania scroll-snap-type, który jest również obecny 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 JavaScript

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

Nie zakładaj, że interfejsy API do przewijania programowego, takie jak Element.scrollTo zawsze kończą się w wymaganym przesunięciu. Po zakończeniu przewijania programowego przesunięcie przewijania może zostać skorygowane. Pamiętaj, że nawet przed wprowadzeniem tej funkcji nie było to dobre założenie, ponieważ przewijanie mogło zostać przerwane z innych powodów, ale szczególnie w przypadku przyciągania.

Przyszłe zadania

Niedawno zespół Chrome przeprowadził ankietę, w której skupiono się na przewijaniu. Wyniki ankiety wskazały kilka obszarów, które wymagają dodatkowej pracy, aby zmniejszyć różnice między bibliotekami wtyczek a CSS. Nadchodzące zadania będą dotyczyć scroll-snap, w tym:

  1. Dostępność interfejsu API i zgodność z różnymi przeglądarkami.
  2. Pracuj nad nowymi interfejsami CSS API, takimi jak scroll-start.
  3. Pracuj nad nowymi zdarzeniami JS, np. snapChanged().