Podstawowe omówienie tworzenia elastycznej wysuwanej nawigacji bocznej
W tym poście chcę przedstawić, jak udało mi się stworzyć prototypowy komponent sieci Sidenav, jest elastyczna, stanowa, obsługuje nawigację za pomocą klawiatury, działa z językiem JavaScript i bez niego, i działa w różnych przeglądarkach. Zobacz prezentację.
Jeśli wolisz film, oto wersja tego posta w YouTube:
Omówienie
Stworzenie elastycznego systemu nawigacyjnego jest trudne. Niektórzy użytkownicy będą używać klawiatury, niektóre mają zaawansowane komputery, a inne – na małych urządzeniach mobilnych. Każda osoba odwiedzająca powinna mieć możliwość otwarcia i zamknięcia menu.
Taktyki internetowe
Podczas tej eksploracji komponentów udało mi się połączyć kilka kluczowych funkcji platformy internetowej:
- Usługa porównywania cen
:target
- Siatka CSS
- Przekształcenia CSS
- Zapytania o multimedia CSS na potrzeby widocznego obszaru i preferencji użytkownika
- JS na potrzeby
focus
ulepszeń UX
Moje rozwiązanie ma jeden pasek boczny i przełącza się tylko w trybie „Urządzenie mobilne” widoczny obszar o szerokości 540px
.
540px
będzie naszym punktem przerwania przy przełączaniu między interaktywnym układem mobilnym a statycznym układem na komputery.
Pseudoklasa usługi porównywania cen :target
Jeden link <a>
ustawia hasz adresu URL na #sidenav-open
, a drugi na pusty (''
).
Element ma atrybut id
pasujący do skrótu:
<a href="#sidenav-open" id="sidenav-button" title="Open Menu" aria-label="Open Menu">
<a href="#" id="sidenav-close" title="Close Menu" aria-label="Close Menu"></a>
<aside id="sidenav-open">
…
</aside>
Kliknięcie każdego z tych linków powoduje zmianę zahaszowania adresu URL naszej strony, a następnie za pomocą pseudoklasy pokazuję i ukrywam boczny pasek nawigacyjny:
@media (max-width: 540px) {
#sidenav-open {
visibility: hidden;
}
#sidenav-open:target {
visibility: visible;
}
}
Siatka CSS
Wcześniej używałem tylko pozycji bezwzględnej lub stałej
układy i komponenty panelu bocznego. Siatka dzięki składni grid-area
pozwala nam przypisać wiele elementów do tego samego wiersza lub kolumny.
Stosy
Głównym elementem układu #sidenav-container
jest siatka, która tworzy 1 wiersz i 2 kolumny.
Jedna z nich ma nazwę stack
. Gdy miejsce jest ograniczone, CSS przypisuje wszystkie atrybuty <main>
dzieci z tą samą nazwą siatki, umieszczając wszystkie elementy w tym samym miejscu i tworząc stos.
#sidenav-container {
display: grid;
grid: [stack] 1fr / min-content [stack] 1fr;
min-height: 100vh;
}
@media (max-width: 540px) {
#sidenav-container > * {
grid-area: stack;
}
}
Tło menu
<aside>
to animowany element, który zawiera boczne elementy nawigacyjne. Zawiera
2 elementy podrzędne: kontener nawigacyjny <nav>
o nazwie [nav]
i tło <a>
o nazwie [escape]
, która służy do zamykania menu.
#sidenav-open {
display: grid;
grid-template-columns: [nav] 2fr [escape] 1fr;
}
Dostosuj 2fr
i 1fr
, aby znaleźć odpowiedni format nakładki menu i jej przycisku zamykania.
Przekształcenia CSS 3D & przejścia
Nasz układ jest teraz układany w stos do rozmiaru widocznego obszaru na urządzeniach mobilnych. Dopóki nie dodam nowych stylów, domyślnie nakłada się na nasz artykuł. W następnej sekcji pokażę, jak zwiększyć wygodę użytkowników.
- Otwieranie i zamykanie
- Animuj z ruchem tylko wtedy, gdy użytkownik wyrazi na to zgodę
- Animuj element
visibility
tak, aby zaznaczenie z klawiatury nie znalazło się w elemencie poza ekranem
Zaczynając wdrażanie animacji animacji, zwróćmy uwagę na ułatwienia dostępu.
Ruch z ułatwieniami dostępu
Nie każdemu przydałaby się ruchoma wysuwana reklama. W naszym rozwiązaniu takie ustawienie
jest stosowany przez dostosowywanie zmiennej CSS --duration
w zapytaniu o media. Ta wartość zapytania o media reprezentuje
ustawienia ruchu w systemie operacyjnym (jeśli są dostępne).
#sidenav-open {
--duration: .6s;
}
@media (prefers-reduced-motion: reduce) {
#sidenav-open {
--duration: 1ms;
}
}
Gdy nawigacja boczna otwiera się i zamyka, użytkownik może preferować zmniejszony ruch, Natychmiast przesuwam element w prawo, utrzymując stan bez ruchu.
Przejście, przekształcenie, tłumaczenie
Sidenav Out (domyślnie)
Aby ustawić domyślny stan nawigacji sidenav na urządzeniu mobilnym na poza ekranem:
Pozycjonuję element za pomocą transform: translateX(-110vw)
.
Uwaga: dodałem kolejny kod 10vw
do typowego kodu poza ekranem: -100vw
,
by element box-shadow
menu bocznego nie wydawał się w głównym widoku, gdy jest ukryty.
@media (max-width: 540px) {
#sidenav-open {
visibility: hidden;
transform: translateX(-110vw);
will-change: transform;
transition:
transform var(--duration) var(--easeOutExpo),
visibility 0s linear var(--duration);
}
}
Sidenav w
Gdy element #sidenav
jest zgodny z wartością :target
, ustaw pozycję translateX()
na wartość Homebase 0
,
i obserwuj, jak CSS przesuwa element
z pozycji wyjściowej -110vw
do „wewnątrz”.
pozycja 0
na var(--duration)
po zmianie haszowania adresu URL.
@media (max-width: 540px) {
#sidenav-open:target {
visibility: visible;
transform: translateX(0);
transition:
transform var(--duration) var(--easeOutExpo);
}
}
Widoczność przejścia
Teraz chcemy ukryć menu przed czytnikami ekranu,
aby systemy nie wyświetlały
menu poza ekranem. Robię to, ustawiając
widoczność po zmianie :target
.
- Gdy włączysz tę funkcję, nie zmieniaj widoczności. być od razu widoczny, żebym mogła przesunąć element i zaakceptować zaznaczenie.
- Widoczność przejścia powinna być opóźniona, tak aby po zakończeniu przejścia została przełączona na
hidden
.
Ulepszenia UX ułatwień dostępu
Linki
Działanie tego rozwiązania wymaga zmiany adresu URL na potrzeby zarządzania stanem.
Oczywiście tutaj należy użyć elementu <a>
, ponieważ zapewnia on pewne ułatwienia dostępu
funkcji bezpłatnie. Dodajmy do naszych elementów interaktywnych etykiety jasno określające intencje.
<a href="#" id="sidenav-close" title="Close Menu" aria-label="Close Menu"></a>
<a href="#sidenav-open" id="sidenav-button" class="hamburger" title="Open Menu" aria-label="Open Menu">
<svg>...</svg>
</a>
Teraz nasze główne przyciski interakcji jasno określają przeznaczenie zarówno myszy, jak i klawiatury.
:is(:hover, :focus)
Ten praktyczny pseudoselektor CSS pozwala nam szybko promować integrację społeczną za pomocą naszych stylów najechania kursorem, udostępniając je również z zaznaczeniem.
.hamburger:is(:hover, :focus) svg > line {
stroke: hsl(var(--brandHSL));
}
Dodawanie elementów JavaScript
Aby zamknąć, naciśnij escape
Klawisz Escape
na klawiaturze powinien zamykać menu? Zaczynajmy.
const sidenav = document.querySelector('#sidenav-open');
sidenav.addEventListener('keyup', event => {
if (event.code === 'Escape') document.location.hash = '';
});
Historia przeglądarki
Aby uniknąć grupowania otwartej i zakończonej interakcji do historii przeglądania, dodaj następujący kod JavaScript do przycisk zamykania:
<a href="#" id="sidenav-close" title="Close Menu" aria-label="Close Menu" onchange="history.go(-1)"></a>
Spowoduje to usunięcie wpisu w historii adresów URL przy zamknięciu, a w ten sposób stanie się tak, jakby menu który nigdy nie został otwarty.
Koncentracja na UX
Następny fragment pomaga skupić się na przyciskach otwierania i zamykania gdy otwierają się lub zamykają. Chcę ułatwić przełączanie się między urządzeniami.
sidenav.addEventListener('transitionend', e => {
const isOpen = document.location.hash === '#sidenav-open';
isOpen
? document.querySelector('#sidenav-close').focus()
: document.querySelector('#sidenav-button').focus();
})
Gdy otworzy się boczna nawigacja, ustaw fokus na przycisku zamykania. Po zamknięciu panelu bocznego
zaznaczyć przycisk otwierania. Wywołuję w tym celu funkcję focus()
w elemencie w JavaScript.
Podsumowanie
Skoro już wiesz, jak to robię, jak Ty?! W ten sposób tworzymy ciekawą architekturę komponentów. Kto przygotuje pierwszą wersję z automatami do gry? 🙂
Zadbajmy o zróżnicowanie i poznaj wszystkie sposoby budowania obecności w internecie. Utwórz usterkę, wyślij mi wiadomość na Twitterze, a dodam ją do Remiksy utworzone przez społeczność poniżej.
Remiksy utworzone przez społeczność
- @_developit z elementami niestandardowymi: demo & kod
- @mayeedwin1 z kodem HTML/CSS/JS: prezentacja kod
- @a_nurella i remiks Glitch: demonstracja kod
- @EvroMalarkey z kodem HTML/CSS/JS: demonstracja kod