Tworzenie komponentu Relacje

Podstawowe informacje o tym, jak utworzyć w internecie funkcję podobną do Instagram Stories.

W tym poście chcę podzielić się przemyśleniami na temat tworzenia komponentu Relacje w internecie, który jest elastyczny, obsługuje nawigację za pomocą klawiatury i działa w różnych przeglądarkach.

Wersja demonstracyjna

Jeśli wolisz zobaczyć, jak samodzielnie utworzyć ten komponent, zapoznaj się z ćwiczeniami z programowania dotyczącymi komponentu Relacje.

Jeśli wolisz obejrzeć film, tutaj znajdziesz wersję tego posta na YouTube:

Przegląd

Dwa popularne przykłady relacji to Snapchat Stories i Instagram Stories (nie wspominając o fleetach). W kontekście wygody użytkowników relacje są zwykle wzorcem nawigacji po wielu subskrypcjach, który jest przeznaczony na urządzenia mobilne i opiera się na kliknięciach. Na przykład na Instagramie użytkownicy otwierają relację znajomego i przeglądają zdjęcia. Zazwyczaj robią to z wieloma znajomymi jednocześnie. Klikając po prawej stronie urządzenia, użytkownik przechodzi do następnej relacji tego znajomego. Przesuwając palcem w prawo, użytkownik przechodzi do innego znajomego. Komponent Relacja jest dość podobny do karuzeli, ale umożliwia poruszanie się po tablicy wielowymiarowej, a nie jednowymiarowej. To tak, jakby w każdej karuzeli była kolejna karuzela. 🤯

Wizualizacja tablicy wielowymiarowej za pomocą kart. Od lewej do prawej znajduje się stos kart z fioletowymi obramowaniami, a wewnątrz każdej karty jest co najmniej 1 karta z cyjanowym obramowaniem. Lista na liście.
Pierwsza karuzela znajomych
Druga „skumulowana” karuzela relacji
👍 Lista na liście, czyli tablica wielowymiarowa

Wybór odpowiednich narzędzi do zadania

Ogólnie rzecz biorąc, ten komponent był dość prosty do utworzenia dzięki kilku kluczowym funkcjom platformy internetowej. Omówmy je.

Siatka CSS

Nasz układ nie okazał się zbyt trudny dla CSS Grid, ponieważ jest on wyposażony w kilka skutecznych sposobów na zarządzanie treścią.

Układ znajomych

Nasz główny komponent .stories to widok przewijania poziomego zoptymalizowany pod kątem urządzeń mobilnych:

.stories {
  inline-size: 100vw;
  block-size: 100vh;

  display: grid;
  grid: 1fr / auto-flow 100%;
  gap: 1ch;

  overflow-x: auto;
  scroll-snap-type: x mandatory;
  overscroll-behavior: contain;
  touch-action: pan-x;
}

/* desktop constraint */
@media (hover: hover) and (min-width: 480px) {
  max-inline-size: 480px;
  max-block-size: 848px;
}
Używanie trybu urządzenia w Narzędziach deweloperskich w Chrome do wyróżniania kolumn utworzonych przez siatkę

Przeanalizujmy układ grid:

  • Na urządzeniach mobilnych wypełniamy widoczny obszar za pomocą 100vh i 100vw, a na komputerach ograniczamy rozmiar.
  • / oddziela szablony wierszy i kolumn.
  • auto-flow oznacza grid-auto-flow: column
  • Szablon automatycznego przepływu to 100%, co w tym przypadku oznacza szerokość okna przewijania.

Na telefonie komórkowym rozmiar wiersza odpowiada wysokości widocznego obszaru, a każda kolumna – jego szerokości. Wracając do przykładu z relacjami na Snapchacie i Instagramie, każda kolumna będzie relacją znajomego. Chcemy, aby relacje znajomych były kontynuowane poza widocznym obszarem, abyśmy mieli gdzie przewijać. Siatka utworzy tyle kolumn, ile potrzeba, aby rozmieścić kod HTML dla każdej relacji znajomego, tworząc dynamiczny i responsywny kontener do przewijania. Grid pozwolił nam scentralizować cały efekt.

Grupowanie

Dla każdego znajomego potrzebujemy jego relacji w stanie gotowym do podziału na strony. Aby przygotować się do animacji i innych ciekawych wzorów, wybrałem stos. Gdy mówię o stosie, mam na myśli widok kanapki z góry, a nie z boku.

Za pomocą siatki CSS możemy zdefiniować siatkę jednokomórkową (czyli kwadrat), w której wiersze i kolumny mają wspólny alias ([story]), a następnie każdy element podrzędny jest przypisywany do tej jednokomórkowej przestrzeni z aliasem:

.user {
  display: grid;
  grid: [story] 1fr / [story] 1fr;
  scroll-snap-align: start;
  scroll-snap-stop: always;
}
.story {
  grid-area: story;
  background-size: cover;
  …
}

Dzięki temu nasz kod HTML kontroluje kolejność stosu, a wszystkie elementy pozostają w przepływie. Zauważ, że nie musieliśmy nic robić z pozycjonowaniem absolute ani z-index i nie musieliśmy korygować pola za pomocą height: 100% ani width: 100%. Siatka nadrzędna określiła już rozmiar widocznego obszaru zdjęcia, więc nie trzeba było informować żadnego z tych komponentów, że ma go wypełnić.

Punkty przyciągania przewijania CSS

Specyfikacja punktów przyciągania przewijania CSS ułatwia blokowanie elementów w widocznym obszarze podczas przewijania. Zanim pojawiły się te właściwości CSS, trzeba było używać JavaScriptu, co było… delikatnie mówiąc, skomplikowane. Więcej informacji o tym, jak ich używać, znajdziesz w artykule Introducing CSS Scroll Snap Points (Wprowadzenie do punktów przyciągania przewijania CSS) autorstwa Sarah Drasner.

Przewijanie poziome bez stylów scroll-snap-points i z nimi. Bez niego użytkownicy mogą swobodnie przewijać stronę. Dzięki temu przeglądarka delikatnie zatrzymuje się na każdym elemencie.
rodzic
.stories {
  display: grid;
  grid: 1fr / auto-flow 100%;
  gap: 1ch;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  overscroll-behavior: contain;
  touch-action: pan-x;
}
Element nadrzędny z overscroll definiuje zachowanie przyciągania.
dziecka
.user {
  display: grid;
  grid: [story] 1fr / [story] 1fr;
  scroll-snap-align: start;
  scroll-snap-stop: always;
}
Dzieci decydują, czy chcą być celem przyciągania.

Wybrałem punkty przyciągania przewijania z kilku powodów:

  • Bezpłatny dostęp. Zgodnie ze specyfikacją punktów przyciągania przewijania naciśnięcie klawiszy strzałki w lewo i strzałki w prawo powinno domyślnie powodować przechodzenie między punktami przyciągania.
  • Rozwijająca się specyfikacja. Specyfikacja punktów przyciągania przewijania jest stale rozwijana i ulepszana, co oznacza, że mój komponent Stories będzie prawdopodobnie coraz lepszy.
  • Łatwość wdrożenia. Punkty przyciągania przewijania są praktycznie stworzone do obsługi poziomego stronicowania na urządzeniach dotykowych.
  • Bezwładność w stylu platformy swobodnej. Każda platforma będzie przewijać i zatrzymywać się we własnym stylu, w przeciwieństwie do znormalizowanej bezwładności, która może mieć nietypowy styl przewijania i zatrzymywania.

Zgodność stron z różnymi przeglądarkami

Przetestowaliśmy je w Operze, Firefoksie, Safari i Chrome oraz na Androidzie i iOS. Oto krótkie podsumowanie funkcji internetowych, w przypadku których znaleźliśmy różnice w możliwościach i obsłudze.

Nie zastosowaliśmy jednak niektórych stylów CSS, więc na niektórych platformach brakuje obecnie optymalizacji UX. Podobało mi się, że nie muszę zarządzać tymi funkcjami, i jestem przekonany, że w końcu trafią one do innych przeglądarek i na inne platformy.

scroll-snap-stop

Karuzele były jednym z głównych przypadków użycia UX, które doprowadziły do utworzenia specyfikacji punktów przyciągania przewijania CSS. W przeciwieństwie do relacji karuzela nie zawsze musi zatrzymywać się na każdym obrazie po interakcji użytkownika. Szybkie przechodzenie przez karuzelę może być akceptowalne lub zalecane. Z kolei relacje najlepiej przeglądać pojedynczo, co umożliwia scroll-snap-stop.

.user {
  scroll-snap-align: start;
  scroll-snap-stop: always;
}

W momencie pisania tego posta interfejs scroll-snap-stop jest obsługiwany tylko w przeglądarkach opartych na Chromium. Aktualne informacje znajdziesz w artykule Zgodność z przeglądarką. Nie jest to jednak czynnik blokujący. Oznacza to tylko, że w nieobsługiwanych przeglądarkach użytkownicy mogą przypadkowo pominąć znajomego. Użytkownicy będą musieli być bardziej ostrożni lub będziemy musieli napisać kod JavaScript, aby upewnić się, że pominięty znajomy nie zostanie oznaczony jako wyświetlony.

Jeśli chcesz dowiedzieć się więcej, przeczytaj specyfikację.

overscroll-behavior

Czy zdarzyło Ci się kiedyś, że podczas przewijania okna modalnego nagle zaczęły się przewijać treści za nim? overscroll-behavior umożliwia deweloperowi przechwycenie przewijania i uniemożliwienie jego opuszczenia. To świetny prezent na każdą okazję. Komponent Moje relacje używa go, aby zapobiec opuszczaniu komponentu przez dodatkowe przesunięcia i gesty przewijania.

.stories {
  overflow-x: auto;
  overscroll-behavior: contain;
}

Safari i Opera to 2 przeglądarki, które nie obsługiwały tej funkcji, i to jest całkowicie w porządku. Użytkownicy będą mogli korzystać z przewijania poza obszar, do którego są przyzwyczajeni, i mogą nawet nie zauważyć tego ulepszenia. Osobiście jestem wielkim fanem tego rozwiązania i staram się je uwzględniać w niemal każdej implementowanej funkcji overscroll. To nieszkodliwy dodatek, który może tylko poprawić wrażenia użytkownika.

scrollIntoView({behavior: 'smooth'})

Gdy użytkownik kliknie i dotrze do końca zestawu relacji znajomego, czas przejść do następnego znajomego w zestawie punktów przyciągania przewijania. Dzięki JavaScriptowi mogliśmy odwołać się do następnego znajomego i poprosić o przewinięcie go do widoku. Obsługa podstawowych funkcji jest świetna – każda przeglądarka przewijała widok do elementu. Jednak nie każda przeglądarka robiła to 'smooth'. Oznacza to, że jest przewijany do widoku, a nie przyciągany.

element.scrollIntoView({
  behavior: 'smooth'
})

Safari była jedyną przeglądarką, która nie obsługiwała behavior: 'smooth' tutaj. Aktualne informacje znajdziesz w artykule Zgodność z przeglądarką.

Praktyczne

Teraz, gdy już wiesz, jak ja to zrobiłem, jak Ty byś to zrobił? Zróżnicujmy nasze podejścia i poznajmy wszystkie sposoby tworzenia stron internetowych. Utwórz wersję demonstracyjną, wyślij mi ją na Twitterze, a ja dodam ją do sekcji Remiksy społeczności poniżej.

Remiksy społeczności