Podstawowy przegląd tworzenia komponentu kart podobnego 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ą częstym elementem systemów projektowania, ale mogą przybierać różne kształty i formy. 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 podstawą korzystania z kart jest obszar nawigacji z przyciskami, który umożliwia przełączanie widoczności treści w ramce wyświetlania. 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łynnych interakcji z użyciem przesuwania i klawiatury z odpowiednimi pozycjami zatrzymania przewijania- Precyzyjne linki za pomocą haszy adresów URL w celu obsługi przewijania na stronie i udostępniania przez przeglądarkę
- Obsługa czytników ekranu za pomocą znaczników elementów
<a>
iid="#hash"
prefers-reduced-motion
do włączania przejść i natychmiastowego przewijania na stronie- Funkcja
@scroll-timeline
w wersji roboczej umożliwia dynamiczne podświetlanie i zmienianie koloru wybranej karty
HTML
Podstawowe zasady UX: kliknij link, adres URL reprezentuje zagnieżdżony stan strony, a następnie obserwuj, jak obszar treści zmienia się, gdy przeglądarka przewija do pasującego elementu.
Znajdują się tam elementy strukturalne treści: 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 skrót linku będzie pasować do sekcji, umożliwiając przeglądarce przewijanie za pomocą kotwicy.
Na przykład kliknięcie linku automatycznie spowoduje skupienie się na artykule :target
w Chrome 89, bez potrzeby korzystania z JS. 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 uporządkowania kart użyłem tego znacznika:
<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ż materiały, możemy rozpocząć układanie.
układy z przewijaniem,
W tym komponencie występują 3 rodzaje obszarów przewijania:
- Pasek nawigacyjny (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.
Istnieją 2 rodzaje elementów związanych z przewijaniem:
- 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). Ustawiłem kierunek na column
, więc nagłówek i sekcja są uporządkowane pionowo. To pierwsze okno przewijania, które ukrywa wszystko, co jest poza zakresem widoczności. Nagłówek i sekcja będą wkrótce obsługiwać przewijanie, tak jak poszczególne 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 przygotowany do pełnienia roli (niebieskiego) kontenera przewijania.
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ępnie style przewijania. Okazuje się, że możemy udostępniać style przewijania między 2 poziomami przewijania poziomego (nagłówek i sekcja), 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 dostępna, 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 kart <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 będą umieszczane artykuły. 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 mówili: „Rozszerz się pionowo tak bardzo, jak to możliwe, ale nie przesadzaj” (pamiętaj o nagłówku ustawionym na flex-shrink: 0
: jest to zabezpieczenie przed takim rozszerzaniem), co 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ą one jednocześnie elementem nadrzędnym i podrzędnym przewijania. Przeglądarka obsługuje tutaj trudne interakcje z użyciem dotyku, 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 ich 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 ważne jest, aby układ działał z włączonym tym ustawieniem, ponieważ chcę 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 ramek okna przewijania jest elementem nadrzędnym flex lub siatki dla układu.
Narzędzia deweloperskie pomagają nam wizualizować:
Układy przewijania są kompletne: mają funkcję przyciągania, umożliwiają tworzenie precyzyjnych linków i są dostępne za pomocą klawiatury. Solidne podstawy, które umożliwiają ulepszanie interfejsu, styl i przyjemność.
Wyróżniona funkcja
Podczas przewijania przytrzymane elementy zachowują swoją pozycję. Oznacza to, że JavaScript nie musi wyświetlać niczego po obróceniu urządzenia ani zmianie rozmiaru przeglądarki. Wypróbuj to w Chromium DevTools w trybie urządzenia, wybierając dowolny tryb inny niż Responsive, a następnie zmień rozmiar ramki urządzenia. Zwróć uwagę, że element pozostaje widoczny i zablokowany wraz z treścią. Jest ona dostępna od czasu, gdy Chromium zaktualizowało implementację, aby była zgodna ze specyfikacją. Więcej informacji znajdziesz w tym poście 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
Można ulepszyć zachowanie ruchu w przypadku :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ń dotyczących ograniczenia ruchu w systemie operacyjnym. W ten sposób wprowadzamy tę funkcję tylko dla osób, które się na to zgadzają.
Wskaźnik kart
Celem tej animacji jest pomoc w powiązaniu wskaźnika ze stanem treści. Postanowiłam użyć stylu border-bottom
dla użytkowników, którzy wolą ograniczony ruch, oraz animacji przesuwania połączonej z kolorowym przejściem dla użytkowników, którym nie przeszkadza ruch.
W Chromium Devtools mogę przełączyć ustawienie i zademonstrować 2 różne style przejścia. Miałem dużo zabawy podczas tworzenia tego projektu.
@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 ma nie tylko podkreślenie marki, ale też ciemniejszy kolor tekstu. Aktywny element ma większy kontrast kolorów tekstu i jasny akcent podświetlenia.
Wystarczy kilka dodatkowych linii kodu CSS, aby użytkownik poczuł, że jest widziany (w tym sensie, że świadomie respektujemy jego preferencje dotyczące animacji). 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 JavaScript. 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 przejdę do klatek kluczowych animacji, chcę zwrócić uwagę, że element tabindicator
będzie animowany na podstawie niestandardowej osi czasu, czyli przewijania sekcji. W ten sposób tworzysz połączenie, ale brakuje ostatniego składnika, czyli punktów stanu, które będą animowane, czyli keyframe’ów.
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 przejdziemy przez elementy potomne i pobierać 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ładowe dane wyjściowe 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 zaczepienia tworzą wyraźne rozgraniczenie między klatkami kluczowymi i znacznie zwiększają wrażenie synchronizacji 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 w momencie wybrania wyróżnionego elementu nawigacji.
Jasniejszy szary kolor niewybranego elementu jest jeszcze bardziej oddalony, gdy wyróżniony element ma większy kontrast. Zmiana koloru tekstu jest powszechna, np. podczas najechania kursorem i po wybraniu, ale przejście koloru podczas przewijania, zsynchronizowane z wskaźnikiem podkreślenia, to już poziom zaawansowania.
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)",
]
Keyframe z kolorem var(--text-active-color)
wyróżnia link, a poza tym ma 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 w ramach karty. Przeglądarka przejdzie na stronie do identyfikatora dopasowanego w haszu 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 powinni. Gdy przewijanie sekcji się zatrzyma, miejsce, w którym się zatrzyma, musi pasować do paska nawigacji u góry.
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) i rozpocznij nową. Gdy przestaniesz przewijać sekcje, nie anuluj limitu czasu i uruchom po 100 ms. 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);
};
Zakładając, że przewijanie jest zablokowane, podzielenie bieżącej pozycji przewijania przez szerokość obszaru przewijania powinno dać 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 elementowi 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? 🙂
Zróżnicujemy nasze podejścia i poznamy wszystkie sposoby tworzenia stron internetowych. Utwórz Glitch, wyślij mi tweeta ze swoją wersją, a ja dodam ją do sekcji Remiksy społeczności poniżej.
Remiksy społeczności
- @devnook, @rob_dodson i @DasSurma z Web Components: artykuł.
- @jhvanderschee z przyciskami: Codepen.