Podstawowy przegląd tworzenia komponentu kart podobnych do tych, które występują w aplikacjach na iOS i Androida.
W tym poście chcę podzielić się z Wami swoimi przemyśleniami na temat tworzenia komponentu kart w internecie, który jest elastyczny, obsługuje różne urządzenia wejściowe i działa w różnych przeglądarkach. Wypróbuj wersję demonstracyjną.
Jeśli wolisz film, oto wersja tego posta w YouTube:
Omówienie
Karty są typowym elementem systemów projektowania, ale mogą przybierać wiele kształtów. Najpierw były karty na komputery, które były tworzone na podstawie elementu <frame>
, a teraz mamy płynne komponenty mobilne, które animują treści na podstawie właściwości fizycznych.
Wszystkie mają ten sam cel: oszczędzanie miejsca.
Obecnie niezbędnym elementem interfejsu kart jest obszar nawigacyjny za pomocą przycisków, który przełącza widoczność treści w ramce wyświetlacza. Wiele różnych obszarów treści zajmuje tę samą przestrzeń, ale są one wyświetlane warunkowo na podstawie przycisku wybranego w nawigacji.
Taktyki internetowe
Ogólnie uważam, że tworzenie tego komponentu było dość proste dzięki kilku kluczowym funkcjom platformy internetowej:
scroll-snap-points
dla płynnego przesuwania i interakcji z klawiaturą z odpowiednimi pozycjami zatrzymania przewijania- Precyzyjne linki w postaci haszy adresu URL na potrzeby obsługi zakotwiczenia i udostępniania przewijania na stronie obsługiwanego przez przeglądarkę.
- Obsługa czytnika ekranu ze znacznikami elementów
<a>
iid="#hash"
prefers-reduced-motion
do włączania przejść płynnych i natychmiastowego przewijania na stronie- Funkcja
@scroll-timeline
w wersji roboczej umożliwia dynamiczne podświetlanie i zmienianie koloru wybranej karty
Kod HTML
Podstawowe zasady UX: kliknij link, aby adres URL reprezentował wbudowany stan strony, a następnie obserwuj, jak obszar treści zmienia się, gdy przeglądarka przewija stronę do pasującego elementu.
Znajdują się tam elementy treści strukturalnych: linki i :target
. Potrzebujemy listy linków, do których świetnie nadaje się <nav>
, oraz listy elementów <article>
, do których świetnie nadaje się <section>
. Każdy hasz linku będzie odpowiadać sekcji, co umożliwia przeglądarce przewijanie przez zakotwiczenie.
Na przykład kliknięcie linku powoduje automatyczne zaznaczenie artykułu :target
w Chrome 89 bez konieczności użycia JavaScriptu. Użytkownik może wtedy przewijać treść artykułu za pomocą urządzenia wejściowego w zwykły sposób. Są to treści uzupełniające, jak wskazano w znaczniku.
Do porządkowania kart zostały użyte następujące znaczniki:
<snap-tabs>
<header>
<nav>
<a></a>
<a></a>
<a></a>
<a></a>
</nav>
</header>
<section>
<article></article>
<article></article>
<article></article>
<article></article>
</section>
</snap-tabs>
Mogę nawiązywać relacje między elementami <a>
i <article>
z usługami href
i id
w ten sposób:
<snap-tabs>
<header>
<nav>
<a href="#responsive"></a>
<a href="#accessible"></a>
<a href="#overscroll"></a>
<a href="#more"></a>
</nav>
</header>
<section>
<article id="responsive"></article>
<article id="accessible"></article>
<article id="overscroll"></article>
<article id="more"></article>
</section>
</snap-tabs>
Następnie wypełniłam artykuły różnymi ilościami tekstu Lorem Ipsum, a linki różnymi długościami i zestawami tytułów obrazów. Teraz, gdy mamy już treści, możemy rozpocząć układanie.
Układy przewijania
W tym komponencie występują 3 rodzaje obszarów przewijania:
- Pasek nawigacji (różowy) można przewijać poziomo.
- Obszar treści (niebieski) można przewijać poziomo.
- Każdy element artykułu (zielony) można przewijać w pionie.
Przewijanie obejmuje 2 różne rodzaje elementów:
- Okno
Pole o określonych wymiarach, które ma styl właściwościoverflow
. - Powierzchnia o niestandardowych rozmiarach
W tym układzie są to kontenery listy: linki nawigacyjne, artykuły w sekcji i treści artykułu.
Układ <snap-tabs>
Wybrałem układ najwyższego poziomu flex (Flexbox). Ustawiam kierunek na column
, więc nagłówek i sekcja są uporządkowane w pionie. To jest nasze pierwsze okno przewijania, które ukrywa wszystko, co jest poza zakresem widoku. Wkrótce nagłówek i sekcja będą używać przewijania ponad ekranem jako oddzielne strefy.
<snap-tabs> <header></header> <section></section> </snap-tabs>
snap-tabs { display: flex; flex-direction: column; /* establish primary containing box */ overflow: hidden; position: relative; & > section { /* be pushy about consuming all space */ block-size: 100%; } & > header { /* defend againstneeding 100% */ flex-shrink: 0; /* fixes cross browser quarks */ min-block-size: fit-content; } }
Wracając do kolorowego diagramu z 3 przewijaniem:
<header>
jest teraz gotowy do użycia jako (różowy) element przewijania.<section>
jest gotowy do użycia jako kontener przewijania (niebieski).
Ramki wyróżnione poniżej za pomocą VisBug pomagają nam zobaczyć okna utworzone przez przewijane kontenery.
Układ kart <header>
Kolejny układ jest prawie taki sam: do tworzenia układu pionowego używam elementu flex.
<snap-tabs> <header> <nav></nav> <span class="snap-indicator"></span> </header> <section></section> </snap-tabs>
header { display: flex; flex-direction: column; }
Element .snap-indicator
powinien przesuwać się poziomo wraz z grupą linków, a ta opcja układu nagłówka pomaga w tym zadaniu. Nie ma tu elementów z pozycji bezwzględnej.
Następne style przewijania. Okazuje się, że możemy udostępniać style przewijania między 2 poziomymi obszarami przewijania (nagłówkiem i sekcją), więc utworzyłem klasę pomocniczą .scroll-snap-x
.
.scroll-snap-x {
/* browser decide if x is ok to scroll and show bars on, y hidden */
overflow: auto hidden;
/* prevent scroll chaining on x scroll */
overscroll-behavior-x: contain;
/* scrolling should snap children on x */
scroll-snap-type: x mandatory;
@media (hover: none) {
scrollbar-width: none;
&::-webkit-scrollbar {
width: 0;
height: 0;
}
}
}
Każdy z nich wymaga przepełnienia na osi x, ograniczeń przewijania, aby zablokować przewijanie, ukrytych suwaków dla urządzeń dotykowych i blokowania obszarów prezentacji treści. Kolejność kart na klawiaturze jest przejrzysta, a wszelkie interakcje kierują uwagę użytkownika w naturalny sposób. Scrolling snap containery mają też ładne interakcje w stylu karuzeli, które można obsługiwać za pomocą klawiatury.
Układ nagłówka karty <nav>
Linki nawigacyjne muszą być wyrównane w linii, bez dzielenia wierszy, a pośrodku. Każdy element linku powinien być dopasowany do kontenera z dopasowaniem do przewijania. Swift działa w ramach usługi porównywania cen 2021.
<nav> <a></a> <a></a> <a></a> <a></a> </nav>
nav { display: flex; & a { scroll-snap-align: start; display: inline-flex; align-items: center; white-space: nowrap; } }
Każdy link ma swój styl i rozmiar, więc układ nawigacji musi określać tylko kierunek i przepływ. Unikalne szerokości elementów nawigacyjnych sprawiają, że przełączanie się między kartami jest przyjemne, ponieważ wskaźnik dostosowuje swoją szerokość do nowego celu. W zależności od tego, ile elementów znajduje się na stronie, przeglądarka wyświetli suwak lub nie.
Układ kart <section>
Ta sekcja jest elementem elastycznym i musi być głównym konsumentem miejsca. Musi też utworzyć kolumny, w których artykuły zostaną umieszczone. Jeszcze raz dziękujemy za szybkie działanie w sprawie usługi porównywania cen w 2021 r. block-size: 100%
rozciąga ten element, aby wypełnił jak najwięcej miejsca w nadrzędnym, a następnie tworzy serię kolumn, które mają 100%
szerokość elementu nadrzędnego. Wartości procentowe sprawdzają się tutaj świetnie, ponieważ nałożyliśmy na element nadrzędny silne ograniczenia.
<section> <article></article> <article></article> <article></article> <article></article> </section>
section { block-size: 100%; display: grid; grid-auto-flow: column; grid-auto-columns: 100%; }
To tak, jakbyśmy mogli powiedzieć „rozwiń w jak najszerszy możliwy w pionie sposób, robiąc nacisk w pionie”
(pamiętaj o nagłówku ustawionym na flex-shrink: 0
: jest to zabezpieczenie przed tym wypchnięciem), które określa wysokość wiersza dla zestawu kolumn o pełnej wysokości. Styl auto-flow
informuje siatkę, aby zawsze układała elementy podrzędne w poziomej linii bez przewijania, co jest dokładnie tym, czego potrzebujemy, aby elementy wypełniały okno nadrzędne.
Czasami trudno mi to zrozumieć. Ten element sekcji mieści się w pudełku, ale utworzył też zestaw pudełek. Mam nadzieję, że obrazy i wyjaśnienia okażą się przydatne.
Układ kart <article>
Użytkownik powinien mieć możliwość przewijania treści artykułu, a paski przewijania powinny wyświetlać się tylko w przypadku przepełnienia. Te elementy artykułu są ułożone w estetyczny sposób. Są jednocześnie elementem nadrzędnym wobec przewijania i elementem podrzędnym przewijania. Przeglądarka obsługuje tutaj trudne interakcje dotykowe, myszy i klawiatury.
<article> <h2></h2> <p></p> <p></p> <h2></h2> <p></p> <p></p> ... </article>
article { scroll-snap-align: start; overflow-y: auto; overscroll-behavior-y: contain; }
Wybrałem, aby artykuły były dopasowywane do swojego głównego scrollera. Bardzo podoba mi się to, że elementy linków nawigacyjnych i elementy artykułu są dopasowywane do początku swoich kontenerów przewijania. Wygląda to na harmonijny związek.
Artykuł jest elementem potomnym siatki, a jego rozmiar jest z góry określony jako obszar widoku, w którym chcemy zapewnić użytkownikowi płynne przewijanie. Oznacza to, że nie muszę tutaj określać wysokości ani szerokości, tylko sposób przepełnienia. Ustawiłem overflow-y na auto, a następnie zablokowałem interakcje z przewijaniem za pomocą przydatnej właściwości overscroll-behavior.
Podsumowanie 3 obszarów przewijania
Poniżej w ustawieniach systemu wybrałem opcję „Zawsze pokazuj suwaki”. Uważam, że działanie układu z włączonym tym ustawieniem jest podwójnie ważne, ponieważ pozwala mi sprawdzić układ i zgodność z przewijaniem.
Widok paska przewijania w tym komponencie pomaga wyraźnie pokazać, gdzie znajdują się obszary przewijania, w jakim kierunku można je przewijać i jak oddziałują na siebie nawzajem. Zastanów się, jak każda z tych ramek przewijania jest też elastyczna lub nadrzędna w stosunku do siatki.
Narzędzia deweloperskie pomagają nam wizualizować:
Układy przewijania są kompletne: skróty, precyzyjne linki i dostępność za pomocą klawiatury. Solidne podstawy do ulepszania UX, stylu i wygody.
Wyróżniona funkcja
Podczas przewijania elementy przypięte zachowują swoją pozycję. Oznacza to, że JavaScript nie musi wyświetlać niczego po obraceniu urządzenia ani zmianie rozmiaru przeglądarki. Wypróbuj je w trybie urządzenia w Narzędziach deweloperskich w Chromium, wybierając tryb inny niż Elastyczny, a następnie zmieniając rozmiar ramki urządzenia. Zwróć uwagę, że element pozostaje widoczny i zablokowany wraz z treścią. Ta funkcja jest dostępna, ponieważ Chromium zaktualizował swoją implementację, by była zgodna ze specyfikacją. Przeczytaj o tym posta na blogu.
Animacja
Celem animacji jest wyraźne powiązanie interakcji z informacjami zwrotnymi interfejsu. Pomaga to użytkownikowi w łatwym znalezieniu wszystkich treści. Dodaję animację w celowy sposób i bezwarunkowo. Użytkownicy mogą teraz określić swoje preferencje dotyczące ruchu w systemie operacyjnym, a ja bardzo chętnie dostosowuję moje interfejsy do ich preferencji.
Połączę podkreślenie karty z pozycją przewijania artykułu. Dopasowywanie to nie tylko ładne wyrównanie, ale też zakotwiczenie początku i końca animacji.
Dzięki temu <nav>
, który działa jak minimapa, pozostaje połączony z treścią.
Sprawdzamy preferencje użytkownika dotyczące animacji zarówno w CSS, jak i JS. Oto kilka świetnych miejsc, w których warto być uprzejmy.
Zachowanie podczas przewijania
Istnieje możliwość poprawy działania funkcji :target
i element.scrollIntoView()
. Domyślnie jest to natychmiastowe. Przeglądarka ustawia tylko pozycję przewijania. Co zrobić, jeśli chcemy przejść do pozycji przewijania zamiast migać?
@media (prefers-reduced-motion: no-preference) {
.scroll-snap-x {
scroll-behavior: smooth;
}
}
Wprowadzamy tu ruch, nad którym użytkownik nie ma kontroli (np. przewijanie), dlatego stosujemy ten styl tylko wtedy, gdy użytkownik nie ma ustawień w systemie operacyjnym dotyczących ograniczenia ruchu. W ten sposób wprowadzamy przewijanie tylko dla osób, które się na to zgadzają.
Wskaźnik kart
Animacja pomaga powiązać wskaźnik ze stanem treści. Postanowiłem użyć przenikania kolorów w stylu border-bottom
dla użytkowników, którzy preferują ograniczenie ruchu, oraz przesuwania palcem z linkiem do przewijania i animacji zanikania kolorów dla użytkowników, którzy lubią ruch.
W Chromium Devtools mogę przełączyć ustawienie i zademonstrować 2 różne style przejścia. Miałem świetną zabawę, tworząc ten projekt.
@media (prefers-reduced-motion: reduce) {
snap-tabs > header a {
border-block-end: var(--indicator-size) solid hsl(var(--accent) / 0%);
transition: color .7s ease, border-color .5s ease;
&:is(:target,:active,[active]) {
color: var(--text-active-color);
border-block-end-color: hsl(var(--accent));
}
}
snap-tabs .snap-indicator {
visibility: hidden;
}
}
Ukrywam .snap-indicator
, gdy użytkownik woli ograniczone ruchy, ponieważ nie jest już potrzebne. Następnie zastępuję je stylami border-block-end
i elementem transition
. Zwróć też uwagę, że podczas interakcji z kartami aktywny element nawigacji nie tylko ma podkreślenie marki, ale też ciemniejszy kolor tekstu. Aktywny element ma większy kontrast kolorów tekstu i jasny akcent podświetlenia.
Kilka dodatkowych wierszy CSS sprawi, że użytkownik poczuje się zauważony (ponieważ szanujemy jego preferencje dotyczące ruchu). Uwielbiam to.
@scroll-timeline
W poprzedniej sekcji pokazałem, jak obsługiwać płynne przejścia między stylami w przypadku ograniczonego ruchu. W tej sekcji pokażę, jak połączyć ze sobą wskaźnik i obszar przewijania. Teraz kilka eksperymentalnych ciekawostek. Mam nadzieję, że nie możesz się już doczekać.
const { matches:motionOK } = window.matchMedia(
'(prefers-reduced-motion: no-preference)'
);
Najpierw sprawdzam preferencje użytkownika dotyczące ruchu w JavaScripcie. Jeśli wynik tego testu to false
, co oznacza, że użytkownik preferuje ograniczone ruchy, nie uruchamiamy żadnych efektów ruchu łączenia podczas przewijania.
if (motionOK) {
// motion based animation code
}
W momencie pisania tego tekstu obsługa przeglądarki dla
@scroll-timeline
nie jest dostępna. Jest to projekt specyfikacji zawierający tylko eksperymentalne implementacje. Ma jednak polyfill, którego używam w tym demo.
ScrollTimeline
Zarówno CSS, jak i JavaScript mogą tworzyć osi czasu przewijania, ale wybrałem JavaScript, aby móc używać w animacji pomiarów elementów na żywo.
const sectionScrollTimeline = new ScrollTimeline({
scrollSource: tabsection, // snap-tabs > section
orientation: 'inline', // scroll in the direction letters flow
fill: 'both', // bi-directional linking
});
Chcę, aby 1 element podążał za pozycją przewijania innego elementu. Tworząc ScrollTimeline
, definiuję element sterujący linkiem przewijania, czyli scrollSource
.
Zazwyczaj animacja w internecie działa zgodnie z globalnym interwałem czasowym, ale dzięki niestandardowemu sectionScrollTimeline
w pamięci mogę to zmienić.
tabindicator.animate({
transform: ...,
width: ...,
}, {
duration: 1000,
fill: 'both',
timeline: sectionScrollTimeline,
}
);
Zanim przejdziemy do klatek kluczowych animacji, warto wskazać element śledzący przewijania – tabindicator
, będzie animowany na podstawie niestandardowej osi czasu, czyli przewijania sekcji. To kończy proces łączenia, ale brakuje nam ostatniego składnika, czyli punktów stanowych, pomiędzy którymi można się poruszać, inaczej zwanych klatek kluczowych.
Klatki kluczowe dynamiczne
Istnieje bardzo skuteczny, czysto deklaratywny sposób tworzenia animacji za pomocą @scroll-timeline
, ale wybrana przeze mnie animacja była zbyt dynamiczna. Nie ma możliwości przejścia między auto
szerokością, a także dynamicznego tworzenia liczby klatek kluczowych na podstawie długości elementów potomnych.
JavaScript wie, jak uzyskać te informacje, więc sami przeanalizujemy elementy podrzędne i pobieramy obliczone wartości w czasie wykonywania:
tabindicator.animate({
transform: [...tabnavitems].map(({offsetLeft}) =>
`translateX(${offsetLeft}px)`),
width: [...tabnavitems].map(({offsetWidth}) =>
`${offsetWidth}px`)
}, {
duration: 1000,
fill: 'both',
timeline: sectionScrollTimeline,
}
);
W przypadku każdego elementu tabnavitem
zdestrukturuj pozycję offsetLeft
i zwróć ciąg znaków, który używa jej jako wartości translateX
. Spowoduje to utworzenie 4 keyframe’ów transformacji dla animacji. To samo dotyczy szerokości. Każdy obrazek pytany jest o swoją dynamiczną szerokość, która jest potem używana jako wartość kluczowego obrazu.
Oto przykładowy wynik na podstawie moich preferencji dotyczących czcionek i przeglądarki:
Klatki kluczowe TranslateX:
[...tabnavitems].map(({offsetLeft}) =>
`translateX(${offsetLeft}px)`)
// results in 4 array items, which represent 4 keyframe states
// ["translateX(0px)", "translateX(121px)", "translateX(238px)", "translateX(464px)"]
Klatki kluczowe szerokości:
[...tabnavitems].map(({offsetWidth}) =>
`${offsetWidth}px`)
// results in 4 array items, which represent 4 keyframe states
// ["121px", "117px", "226px", "67px"]
Aby podsumować strategię, wskaźnik karty będzie się teraz animować w 4 klatkach kluczowych w zależności od pozycji przyciągania sekcji w rolce. Punkty przyciągania tworzą wyraźne odgraniczenie między klatkami kluczowymi i dodają zsynchronizowanego charakteru animacji.
Użytkownik uruchamia animację za pomocą interakcji, a szerokość i położenie wskaźnika zmieniają się z sekcji na sekcję, idealnie dopasowując się do przewijania.
Może nie zauważysz, ale jestem bardzo dumny z przejścia koloru, gdy zaznaczony element nawigacji staje się zaznaczony.
Odznaczony jaśniejszy kolor szarości wydaje się jeszcze bardziej odsunięty, gdy wyróżniony element ma większy kontrast. Często zmienia się kolor przejścia w tekście, np. po najechaniu kursorem i po zaznaczeniu. Kolejnym poziomem jest przejście tego koloru przy przewijaniu, zsynchronizowane ze wskaźnikiem podkreślenia.
Oto jak to zrobiłem:
tabnavitems.forEach(navitem => {
navitem.animate({
color: [...tabnavitems].map(item =>
item === navitem
? `var(--text-active-color)`
: `var(--text-color)`)
}, {
duration: 1000,
fill: 'both',
timeline: sectionScrollTimeline,
}
);
});
Każdy link nawigacyjny na karcie musi mieć tę nową animację kolorów, która śledzi tę samą oś czasu przewijania co podkreślenie. Używam tej samej osi czasu co wcześniej: ponieważ jej zadaniem jest emitowanie znacznika wyboru podczas przewijania, możemy go używać w dowolnym typie animacji. Tak jak wcześniej, w pętli utworzyłem 4 kluczowe klatki i zwracam kolory.
[...tabnavitems].map(item =>
item === navitem
? `var(--text-active-color)`
: `var(--text-color)`)
// results in 4 array items, which represent 4 keyframe states
// [
"var(--text-active-color)",
"var(--text-color)",
"var(--text-color)",
"var(--text-color)",
]
Klatka kluczowa o kolorze var(--text-active-color)
wyróżnia link. W przeciwnym razie jest to standardowy kolor tekstu. Zagnieżdżona pętla sprawia, że jest to stosunkowo proste, ponieważ pętla zewnętrzna to każdy element nawigacji, a pętla wewnętrzna to osobne klatki kluczowe każdego z tych elementów. Sprawdzam, czy element zewnętrznego pętli jest taki sam jak element wewnętrznego pętli, i na tej podstawie określam, kiedy jest wybrany.
Miałem dużo zabawy, pisząc ten artykuł. Ogromnie.
Jeszcze więcej ulepszeń JavaScriptu
Warto przypomnieć, że główna część tego, co tu pokazuję, działa bez JavaScriptu. Zobaczmy, jak możemy to ulepszyć, gdy JavaScript jest dostępny.
Precyzyjne linki
Precyzyjne linki to termin bardziej związany z urządzeniami mobilnymi, ale myślę, że intencje związane z precyzyjnymi linkami są spełnione dzięki temu, że możesz udostępniać adres URL bezpośrednio do zawartości karty. Przeglądarka przejdzie na stronę pod identyfikator zgodny z haszem adresu URL. Okazało się, że ten onload
handler działa na różnych platformach.
window.onload = () => {
if (location.hash) {
tabsection.scrollLeft = document
.querySelector(location.hash)
.offsetLeft;
}
}
Synchronizacja końca przewijania
Nasi użytkownicy nie zawsze klikają lub używają klawiatury. Czasami po prostu przewijają bez przeszkód, jak to powinno być. Gdy przewijak sekcji przestanie przewijać, miejsce, w którym się znajduje, musi zostać dopasowane na górnym pasku nawigacyjnym.
Oto jak czekam na koniec przewijania:
js
tabsection.addEventListener('scroll', () => {
clearTimeout(tabsection.scrollEndTimer);
tabsection.scrollEndTimer = setTimeout(determineActiveTabSection, 100);
});
Gdy przewijasz sekcje, wyczyść limit czasu sekcji, jeśli jest dostępny, i rozpocznij nową. Gdy przestaniesz przewijać sekcje, nie czyść limitu czasu i uruchamiaj funkcję po 100 ms od zakończenia odpoczynku. Gdy zostanie wywołany, wywołuje funkcję, która określa, gdzie użytkownik zatrzymał się w odtwarzaniu.
const determineActiveTabSection = () => {
const i = tabsection.scrollLeft / tabsection.clientWidth;
const matchingNavItem = tabnavitems[i];
matchingNavItem && setActiveTab(matchingNavItem);
};
Przy założeniu, że przewinięcie zostało przyciągnięte, podzielenie bieżącej pozycji przewijania od szerokości obszaru przewijania powinno przynieść liczbę całkowitą, a nie ułamek dziesiętny. Następnie próbuję pobrać element nawigacyjny z naszej pamięci podręcznej za pomocą tego wyliczonego indeksu. Jeśli coś znajdzie, wysyłam dopasowanie, aby ustawić je jako aktywne.
const setActiveTab = tabbtn => {
tabnav
.querySelector(':scope a[active]')
.removeAttribute('active');
tabbtn.setAttribute('active', '');
tabbtn.scrollIntoView();
};
Ustawienie aktywnej karty rozpoczyna się od wyczyszczenia wszystkich obecnie aktywnych kart, a następnie nadania atrybutu aktywnego stanu do elementu nawigacji przychodzącej. Wywołanie funkcji scrollIntoView()
ma ciekawą interakcję z usługą porównywania cen, na którą warto zwrócić uwagę.
.scroll-snap-x {
overflow: auto hidden;
overscroll-behavior-x: contain;
scroll-snap-type: x mandatory;
@media (prefers-reduced-motion: no-preference) {
scroll-behavior: smooth;
}
}
W CSS narzędzia do korzystania z przewijania poziomego zagnieżdżyliśmy zapytanie o media, które stosuje przewijanie smooth
, jeśli użytkownik toleruje ruch. Kod JavaScript może swobodnie wywoływać metody, aby przewijać elementy do widoku, a kod CSS może deklaratywnie zarządzać UX.
Czasami tworzą naprawdę urocze pary.
Podsumowanie
Teraz, gdy już wiesz, jak to zrobić, jak Ty to zrobisz? To tworzy ciekawą architekturę komponentów. Kto przygotuje pierwszą wersję z miejscami na reklamy w ulubionej platformie? 🙂
Stosujmy różne podejścia i poznajmy sposoby budowania obecności w internecie. Utwórz Glitch, wyślij mi tweeta ze swoją wersją, a ja dodam ją do sekcji Remiksy społeczności poniżej.
Remiksy utworzone przez społeczność
- @devnook, @rob_dodson i @DasSurma z komponentami sieciowymi: artykuł.
- @jhvanderschee z przyciskami: Codepen.