Tworzenie komponentu przewijającego multimedia

Podstawowe informacje o tworzeniu elastycznego widoku z przewijaniem w poziomie na telewizory, telefony, komputery itp.

W tym poście przedstawię sposoby na tworzenie stron z przewijaniem poziomym, które nie wymaga wiele wysiłku, są szybko i łatwo dostępne i działają w różnych przeglądarkach i na różnych platformach (np. na telewizorach). Zobacz prezentację.

Demonstracja

Jeśli wolisz film, oto wersja tego posta na YouTube:

Przegląd

Utworzymy poziomy układ z przewijaniem przeznaczonym do przechowywania miniatur multimediów lub produktów. Na początku komponent składa się z skróconej listy <ul>, ale za pomocą CSS przekształca go w satysfakcjonujące i płynne przewijanie, które pozwala wyświetlać obrazy i przyciągać je do siatki. Dodano JavaScript, aby ułatwić interakcje z indeksem i ułatwiać użytkownikom klawiatury pomijanie ponad 100 elementów. Dodatkowo eksperymentalne zapytanie o multimedia (prefers-reduced-data) jest wykorzystywane do przekształcania kółka przewijania multimediów w lekkie przewijanie tytułów.

Zacznij od znaczników ułatwień dostępu

Przewijanie multimediów składa się tylko z kilku podstawowych komponentów – listy elementów. Lista w najprostszej formie może podróżować po całym świecie i być łatwo dostępna dla wszystkich. Użytkownik, który wejdzie na tę stronę, może przejrzeć listę i kliknąć link, aby wyświetlić produkt. To nasza dostępna baza.

Przesyłanie listy z elementem <ul>:

<ul class="horizontal-media-scroller">
  <li></li>
  <li></li>
  <li></li>
  ...
<ul>

Dodaj element <a>, aby elementy listy były interaktywne:

<li>
  <a href="#">
    ...
  </a>
</li>

Do semantycznego przedstawienia obrazu i jego podpisu użyj elementu <figure>:

<figure>
  <picture>
    <img alt="..." loading="lazy" src="https://picsum.photos/500/500?1">
  </picture>
  <figcaption>Legends</figcaption>
</figure>

Zwróć uwagę na atrybuty alt i loading na stronie <img>. Tekst alternatywny dla przewijania multimediów to możliwość UX, która pomaga nadać miniaturom dodatkowy kontekst lub jako tekst zastępczy, gdy obraz nie został wczytany lub zapewnia interfejs głosowy dla użytkowników technologii wspomagającej osoby z niepełnosprawnością, takich jak czytnik ekranu. Dowiedz się więcej o 5 złotych regułach zgodnych tekstu alternatywnego.

Atrybut loading akceptuje słowo kluczowe lazy jako sygnał, że źródło obrazu ma zostać pobrane tylko wtedy, gdy obraz znajdzie się w widocznym obszarze. Może to być bardzo przydatne w przypadku dużych list, ponieważ użytkownicy będą pobierać obrazy tylko tych elementów, które przewiną widok.

Obsługuj preferencję schematu kolorów użytkownika

Użyj color-scheme jako tagu <meta>, aby zasygnalizować przeglądarce, że Twoja strona chce używać zarówno jasnego, jak i ciemnego stylu klienta użytkownika. To bezpłatny lub jasny tryb ciemny, w zależności od tego, jak na niego patrzysz.

<meta name="color-scheme" content="dark light">

Metatag zapewnia najwcześniejszy możliwy sygnał, więc przeglądarka może wybrać domyślny kolor ciemnego tła, jeśli użytkownik ma ustawiony ciemny motyw. Oznacza to, że podczas przechodzenia między stronami w witrynie nie będzie migać białe tło. Płynny ciemny motyw między wczytywaniem, znacznie ładniejszy dla oka.

Aby dowiedzieć się więcej na temat Thomasa Steinera, wejdź na https://web.dev/color-scheme/.

Dodaj treść

Biorąc pod uwagę powyższą strukturę treści ul > li > a > figure > picture > img, kolejnym zadaniem jest dodanie obrazów i tytułów do przewinięcia. W wersji demonstracyjnej znajdziesz statyczne obrazy zastępcze i tekst, ale możesz też wykorzystać swoje ulubione źródło danych.

Dodaj styl za pomocą CSS

Pora wykorzystać tę ogólną listę treści w usługę porównywania cen. Netflix, App Store i wiele innych witryn i aplikacji korzystają z obszarów, które można przewijać w poziomie, aby zapełnić widoczny obszar o kategorie i opcje.

Tworzenie układu przewijania

Unikaj obcinania treści w układach i używania wielokropka. Wiele telewizorów ma takie same narzędzia do przewijania multimediów, ale zbyt często w swoich treściach uzależniają się od pojedynczych materiałów. Ten układ nie. Pozwala też treści multimedialnej zastępować rozmiar kolumny, dzięki czemu jeden układ jest wystarczająco elastyczny, aby obsłużyć wiele interesujących kombinacji.

Wyświetlam 2 przewijane wiersze. Jeden nie ma wielokropka, co oznacza, że jest wyższy, a każdy tytuł jest w pełni czytelny. Drugi jest krótszy i wiele tytułów jest uciętych
i zawiera wielokropek.

Kontener umożliwia zastąpienie rozmiaru kolumny przez podanie domyślnego rozmiaru jako właściwości niestandardowej. Ten układ siatki jest oceniany pod kątem rozmiaru kolumny, a tylko zarządzanie odstępami i kierunkiem:

.horizontal-media-scroller {
  --size: 150px;

  display: grid;
  grid-auto-flow: column;
  gap: calc(var(--gap) / 2); /* parent owned value for children to be relative to*/
  margin: 0;
}

Właściwość niestandardowa jest następnie używana przez element <picture> do utworzenia podstawowego współczynnika proporcji: ramkę:

.horizontal-media-scroller {
  --size: 150px;

  display: grid;
  grid-auto-flow: column;
  gap: calc(var(--gap) / 2);
  margin: 0;

  & picture {
    inline-size: var(--size);
    block-size: var(--size);
  }
}

Jeszcze tylko kilka drobnych stylów i dokończ przewijanie multimediów:

.horizontal-media-scroller {
  --size: 150px;

  display: grid;
  grid-auto-flow: column;
  gap: calc(var(--gap) / 2);
  margin: 0;

  overflow-x: auto;
  overscroll-behavior-inline: contain;

  & > li {
    display: inline-block; /* removes the list-item bullet */
  }

  & picture {
    inline-size: var(--size);
    block-size: var(--size);
  }
}

Ustawienie overflow powoduje, że <ul>umożliwia przewijanie i nawigowanie po liście za pomocą klawiatury. Z kolei każdy bezpośredni element podrzędny <li> zostaje usunięty ::marker po wprowadzeniu nowego typu wyświetlania inline-block.

Jeszcze nie reagują i wyglądają z pudełek, w których się znajdują. Dostosuj je do różnych rozmiarów, dopasowania i stylów obramowania oraz gradientu tła, gdy są leniwe ładowanie.

img {
  /* smash into whatever box it's in */
  inline-size: 100%;
  block-size: 100%;

  /* don't squish but do cover the space */
  object-fit: cover;

  /* soften the edges */
  border-radius: 1ex;
  overflow: hidden;

  /* if empty, show a gradient placeholder */
  background-image:
    linear-gradient(
      to bottom,
      hsl(0 0% 40%),
      hsl(0 0% 20%)
    );
}

Dopełnienie przewijania

Aby stworzyć harmonijny, minimalistyczny komponent, niezbędne jest wyrównanie zawartości strony oraz powierzchnia przewijania od krawędzi do krawędzi.

Aby układ przewijania od krawędzi do krawędzi był dopasowany do typografii i linii układu, użyj padding zgodnego z elementem scroll-padding:

.horizontal-media-scroller {
  --size: 150px;

  display: grid;
  grid-auto-flow: column;
  gap: calc(var(--gap) / 2);
  margin: 0;

  overflow-x: auto;
  overscroll-behavior-inline: contain;

  padding-inline: var(--gap);
  scroll-padding-inline: var(--gap);
  padding-block: calc(var(--gap) / 2); /* make space for scrollbar and focus outline */
}

Poprawka błędu dopełnienia przewijania w poziomie Powyższa sekcja pokazuje, jak łatwo można zamknąć kontener przewijania, ale występują w nim poważne problemy ze zgodnością (naprawiono to jednak w Chromium w wersji 91 i nowszych). Więcej informacji na ten temat znajdziesz tutaj, ale w skróconej wersji dopełnienie nie zawsze było uwzględniane w widoku przewijania.

W okolicach ostatniego elementu listy wyróżnione jest pole, w którym dopełnienie i element mają taką samą szerokość jak w przypadku żądanego wyrównania.

Aby nakłonić przeglądarki do umieszczenia dopełnienia na końcu suwaka przewijania, kieruję reklamy na ostatnią wartość na każdej liście i dołączam pseudoelement, który odpowiada wymaganej ilości dopełnienia.

.horizontal-media-scroller > li:last-of-type figure {
  position: relative;

  &::after {
    content: "";
    position: absolute;

    inline-size: var(--gap);
    block-size: 100%;

    inset-block-start: 0;
    inset-inline-end: calc(var(--gap) * -1);
  }
}

Dzięki właściwościom logicznym przewijany multimediów może działać w dowolnym trybie pisania i w dowolnym kierunku dokumentu.

Przyciąganie po przewinięciu

Przewijany kontener z przepełnieniem może stać się przyciągającym widocznym obszarem z jednym wierszem kodu CSS. To na kontach podrzędnych klient samodzielnie ustala, jak mają się wyrównać.

.horizontal-media-scroller {
  --size: 150px;

  display: grid;
  grid-auto-flow: column;
  gap: calc(var(--gap) / 2);
  margin: 0;

  overflow-x: auto;
  overscroll-behavior-inline: contain;

  padding-inline: var(--gap);
  scroll-padding-inline: var(--gap);
  padding-block-end: calc(var(--gap) / 2);

  scroll-snap-type: inline mandatory;

  & figure {
    scroll-snap-align: start;
  }
}

główny temat filmu,

Ten komponent pochodzi m.in. z ogromnej popularności na telewizorach i w App Store. Wiele platform gier wideo używa bardzo podobnego do niego elementu przewijania, który jest podstawowym układem ekranu głównego. Skoncentrowanie się na UX to nie tylko drobnostki. Wyobraź sobie, że używasz pilota, z kanapy, i dodaj kilka drobnych ulepszeń:

.horizontal-media-scroller a {
  outline-offset: 12px;

  &:focus {
    outline-offset: 7px;
  }

  @media (prefers-reduced-motion: no-preference) {
    & {
      transition: outline-offset .25s ease;
    }
  }
}

Spowoduje to odsunięcie stylu konturu zaznaczenia 7px od pola i udzielenie mu odpowiedniego odstępu. Jeśli użytkownik nie ma żadnych preferencji dotyczących ruchu związanego z zmniejszaniem ruchu, przesunięcie zostanie przeniesione, zapewniając delikatny ruch w obszarze skupienia.

Indeks ruchu

Użytkownicy padów do gier i klawiatury potrzebują szczególnej uwagi na tych długich listach z treściami i opcjami przewijania. Typowy wzorzec rozwiązywania tego problemu nosi nazwę indeksu przemierzania. Dzieje się tak, gdy kontener elementów jest aktywny za pomocą klawiatury, ale tylko 1 element podrzędny może w danym momencie zatrzymać zaznaczenie. Ten 1 element, który można zaznaczyć w tym samym czasie, ma umożliwiać ominięcie potencjalnie długiej listy elementów, a nie konieczność naciskania klawisza Tab ponad 50 razy, aby dotrzeć do końca.

W pierwszym przewijaniu prezentacji znajduje się 300 elementów. Możemy zrobić znacznie więcej niż zmuszenie ich do przemierzenia ich i dotarcia do następnej sekcji.

Aby utworzyć to doświadczenie, JavaScript musi obserwować zdarzenia klawiatury i zdarzenia zaznaczenia. Utworzyłem niewielką bibliotekę open source w formacie npm, aby ułatwić użytkownikom korzystanie z tej funkcji. Oto jak to zrobić w przypadku 3 rolek:

import {rovingIndex} from 'roving-ux';

rovingIndex({
  element: someElement
});

Ta wersja demonstracyjna wysyła zapytanie do dokumentu w odpowiedzi na przewijaki i w przypadku każdej z nich wywołuje funkcję rovingIndex(). Przekaż element rovingIndex(), aby uzyskać środowisko wykonawcze, np. kontener listy i selektor docelowego zapytania, na wypadek gdyby cele kierowania nie są bezpośrednimi elementami podrzędnymi.

document.querySelectorAll('.horizontal-media-scroller')
  .forEach(scroller =>
    rovingIndex({
      element: scroller,
      target: 'a',
}))

Więcej informacji o tym efektie znajdziesz w bibliotece open source roving-ux.

Współczynnik proporcji

W momencie napisania tego posta obsługa aspect-ratio jest ukryta w przeglądarce Firefox, ale jest dostępna w przeglądarkach Chromium i dekoderach. Układ siatki przewijania multimediów określa tylko kierunek i odstępy, dlatego rozmiar może się zmieniać w zapytaniu o multimedia, które sprawdza obsługę współczynnika proporcji. Stopniowe ulepszenie kilku bardziej dynamicznych elementów przewijania.

Pole o proporcjach 4:4 wyświetla się obok innych współczynników proporcji 16:9 i 4:3.

@supports (aspect-ratio: 1) {
  .horizontal-media-scroller figure > picture {
    inline-size: auto; /* for a block-size driven ratio */
    aspect-ratio: 1; /* boxes by default */

    @nest section:nth-child(2) & {
      aspect-ratio: 16/9;
    }

    @nest section:nth-child(3) & {
      /* double the size of the others */
      block-size: calc(var(--size) * 2);
      aspect-ratio: 4/3;

      /* adjust size to fit more items into the viewport */
      @media (width <= 480px) {
        block-size: calc(var(--size) * 1.5);
      }
    }
  }
}

Jeśli przeglądarka obsługuje składnię aspect-ratio, obrazy przewijane treści multimedialne są uaktualniane do rozmiarów aspect-ratio. Dzięki składni zagnieżdżania wersji roboczej każde zdjęcie zmienia swój format obrazu w zależności od tego, czy znalazł się w pierwszym, drugim czy trzecim wierszu. Składnia zagnieżdżenia umożliwia też wprowadzanie niewielkich dostosowań w widocznym obszarze bezpośrednio z innymi regułami rozmiaru.

W przypadku tego kodu CSS funkcja jest dostępna w większej liczbie przeglądarek, dlatego układ ułatwia zarządzanie, ale jest bardziej atrakcyjny wizualnie.

Preferuje zmniejszoną ilość danych

Kolejna metoda jest dostępna tylko za flagą w Canary, chcę jednak pokazać, jak za pomocą kilku wierszy CSS mogę zaoszczędzić sporo czasu wczytywania strony i wykorzystania danych. Zapytanie o multimedia prefers-reduced-data z poziomu 5 pozwala sprawdzić, czy urządzenie ma określony stan z ograniczoną ilością danych, np. tryb oszczędzania danych. Jeśli tak, mogę zmodyfikować dokument, a tym razem ukryć obrazy.

ALT_TEXT_HERE

figure {
  @media (prefers-reduced-data: reduce) {
    & {
      min-inline-size: var(--size);

      & > picture {
        display: none;
      }
    }
  }
}

Treść jest nadal dostępna do nawigacji, ale bez kosztów pobierania ciężkich obrazów. Oto strona przed dodaniem CSS prefers-reduced-data:

(7 żądań, 100 KB zasobów w 131 ms)

ALT_TEXT_HERE

Oto wydajność witryny po dodaniu usługi porównywania cen prefers-reduced-data:

ALT_TEXT_HERE

(71 żądań, 1,2 MB zasobów w wersji 1.07)

64 żądań mniej, to ok. 60 obrazów w widocznym obszarze (testy przeprowadzone na wyświetlaczu szerokoekranowym) tej karty przeglądarki, zwiększenie wczytywania strony o około 80% i 10% danych przesyłanych przewodowo. Imponujący CSS.

Podsumowanie

Skoro już wiesz, jak to udało mi się osiągnąć, to jak? 🙂

Stwórzmy różne metody i nauczmy się wszystkiego, jak rozwijać się w internecie. Utwórz program Codepen lub udostępnij własną prezentację i prześlij mi go na tweeta, a dodam ją do sekcji remiksów ze społeczności poniżej.

Źródło

Remiksy społeczności

Nic tu jeszcze nie ma.