Podstawowe informacje o tworzeniu elastycznego wysuwanego panelu bocznego
W tym poście przedstawię prototypowanie internetowego komponentu Sidenav, który jest elastyczny, stanowy, obsługuje nawigację za pomocą klawiatury, obsługuje JavaScript i bez niego oraz działa w różnych przeglądarkach. Zobacz prezentację.
Jeśli wolisz film, oto wersja tego posta na YouTube:
Przegląd
Stworzenie elastycznego systemu nawigacji jest trudne. Część użytkowników korzysta z klawiatury, inni na zaawansowanych komputerach, a jeszcze inni na małych urządzeniach mobilnych. Wszyscy odwiedzający powinni mieć możliwość otwierania i zamykania menu.
Taktyki internetowe
W ramach tej eksploracji składowej udało mi się połączyć kilka ważnych funkcji platformy internetowej:
- Usługa porównywania cen
:target
- Siatka CSS
- transforms CSS
- Zapytania o multimedia w CSS na potrzeby widocznego obszaru i preferencji użytkownika
- Biblioteka JS
focus
ulepszenia UX
Moje rozwiązanie ma 1 pasek boczny i przełącza się tylko wtedy, gdy znajduje się w widocznym obszarze na poziomie „mobilnym” nieprzekraczającym 540px
.
540px
będzie naszym punktem przerwania przy przełączaniu się między interfejsem interaktywnym na urządzenia mobilne a układem statycznym na komputery.
Pseudoklasa CSS :target
Jeden link <a>
ustawia hasz adresu URL na #sidenav-open
, a drugi jest pusty (''
).
Ostatni element zawiera parametr id
odpowiadający haszu:
<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 zmienia stan skrótu adresu URL naszej strony, a potem dzięki pseudoklasie wyświetlam i ukrywam panel boczny:
@media (max-width: 540px) {
#sidenav-open {
visibility: hidden;
}
#sidenav-open:target {
visibility: visible;
}
}
Siatka CSS
Dawniej używałam układów i komponentów
nawigacji bocznej z bezwzględnymi lub stałymi pozycjami. Jednak dzięki składni grid-area
można przypisać wiele elementów do tego samego wiersza lub kolumny.
Stosy
Podstawowy element układu #sidenav-container
to siatka, która tworzy jeden wiersz i 2 kolumny. Jedna z nich ma nazwę stack
. Gdy przestrzeń jest ograniczona, CSS przypisuje wszystkie elementy podrzędne elementu <main>
do tej samej nazwy siatki, umieszczając wszystkie elementy w tej samej przestrzeni 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 element animowany zawierający boczny panel nawigacyjny. Ma
dwa elementy podrzędne: kontener nawigacyjny <nav>
o nazwie [nav]
i tło <a>
o nazwie [escape]
, które służy do zamykania menu.
#sidenav-open {
display: grid;
grid-template-columns: [nav] 2fr [escape] 1fr;
}
Dostosuj ustawienia 2fr
i 1fr
, aby znaleźć odpowiedni współczynnik proporcji nakładki menu i jej przycisku zamykania.
Przekształcenia i przejścia CSS 3D
Nasz układ jest teraz warstwowy w rozmiarze widocznego obszaru na urządzeniach mobilnych. Dopóki nie dodam nowych stylów, domyślnie nakłada się on na artykuł. W następnej sekcji chcę podać kilka informacji o wrażeniach użytkownika:
- Animacja otwarcia i zamykania
- Animuj z ruchem tylko wtedy, gdy użytkownik to akceptuje
- Animuj
visibility
tak, aby zaznaczenie z klawiatury nie wprowadzało elementu poza ekranem
Zaczynając implementowanie animacji ruchu, chcę zacząć od ułatwień dostępu.
Ruch z ułatwieniami dostępu
Nie każdy chciałby mieć możliwość wysunięcia się z niego. W naszym rozwiązaniu tę preferencję stosujemy, dostosowując zmienną CSS --duration
w zapytaniu o media. Wartość zapytania o multimedia to preferencja użytkownika w zakresie ruchu w systemie operacyjnym (jeśli jest dostępna).
#sidenav-open {
--duration: .6s;
}
@media (prefers-reduced-motion: reduce) {
#sidenav-open {
--duration: 1ms;
}
}
Teraz, gdy pasek boczny przesuwa się w górę i w dół, a użytkownik preferuje zmniejszony ruch, natychmiast przesuwam element w widoku, zachowując jego stan bez ruchu.
Przejście, przekształcenie, tłumaczenie
Sidenav Out (domyślnie)
Aby ustawić domyślny stan panelu bocznego na urządzeniu mobilnym w trybie poza ekranem, ustawiam element za pomocą transform: translateX(-110vw)
.
Dodaję kolejny 10vw
do typowego kodu spoza ekranu -100vw
, aby mieć pewność, że box-shadow
panelu bocznego nie zasłania widoku głównego widocznego obszaru, 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
będzie zgodny z wartością :target
, ustaw pozycję translateX()
na bazę główną 0
i obserwuj, jak CSS przesuwa element z pozycji poza nią (-110vw
) na pozycję „0
” zamiast „var(--duration)
” po zmianie skrótu adresu URL.
@media (max-width: 540px) {
#sidenav-open:target {
visibility: visible;
transform: translateX(0);
transition:
transform var(--duration) var(--easeOutExpo);
}
}
Widoczność przejścia
Obecnie celem jest ukrycie menu przed czytnikami ekranu, gdy jest ono wyłączone, a systemy nie umieszczają w nim opcji poza ekranem. Jest to możliwe dzięki ustawieniu
widocznego przejścia po zmianie parametru :target
.
- Zadbaj o to, aby elementy były widoczne od razu. Gdy się pojawią, pokaż element, który się wysunie, i zaznacz, że jest aktywny.
- Gdy wychodzisz, włącz widoczność przejścia z opóźnieniem, aby na końcu przejść do
hidden
.
Ulepszenia ułatwień dostępu
Linki
To rozwiązanie wymaga zmiany adresu URL w celu umożliwienia zarządzania stanem.
Tu należy użyć elementu <a>
i bezpłatnie uzyskać do niego przydatne funkcje ułatwień dostępu. Ozdóbmy nasze elementy interaktywne etykietami, które jasno przedstawiają 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 jasno określają one przeznaczenie myszy i klawiatury.
:is(:hover, :focus)
Dzięki temu praktycznemu pseudoselektorowi CSS możemy szybko dodawać elementy do stylów, które są pokazywane po najechaniu kursorem.
.hamburger:is(:hover, :focus) svg > line {
stroke: hsl(var(--brandHSL));
}
Posypka w języku JavaScript
Aby zamknąć, naciśnij escape
Klawisz Escape
na klawiaturze powinien zamknąć menu? Podłączmy to pod prąd.
const sidenav = document.querySelector('#sidenav-open');
sidenav.addEventListener('keyup', event => {
if (event.code === 'Escape') document.location.hash = '';
});
Historia przeglądarki
Aby uniemożliwić interakcję otwierania i zamykania w historii przeglądarki wielu wpisów, dodaj do przycisku zamykającego ten kod JavaScript:
<a href="#" id="sidenav-close" title="Close Menu" aria-label="Close Menu" onchange="history.go(-1)"></a>
Przy zamknięciu zostanie usunięty wpis historii adresów URL, przez co menu nie będzie nigdy otwierane.
Skup się na wrażeniach użytkownika
Następny fragment pomaga nam skupić się na przyciskach otwierania i zamykania, gdy są one otwierane lub zamykane. Chcę ułatwić sobie przełączanie.
sidenav.addEventListener('transitionend', e => {
const isOpen = document.location.hash === '#sidenav-open';
isOpen
? document.querySelector('#sidenav-close').focus()
: document.querySelector('#sidenav-button').focus();
})
Po otwarciu panelu bocznego zaznacz przycisk zamykania. Po zamknięciu panelu nawigacyjnego
upewnij się, że przycisk otwierania jest otwarty. Wywołuję focus()
w elemencie w JavaScript.
Podsumowanie
Skoro już wiesz, jak to udało mi się osiągnąć, to jak? W ten sposób powstaje zabawna architektura komponentów. Kto utworzy pierwszą wersję z przedziałami? 🙂
Przeanalizujmy różne podejścia i nauczmy się korzystać z internetu. Utwórz glitch i napisz mi swoją wersję, a dodam ją do sekcji Remiksy społeczności poniżej.
Remiksy społeczności
- @_developit z elementami niestandardowymi: demonstracja i kod
- @mayeedwin1 z HTML/CSS/JS: prezentacja i kod
- @a_nurella z remiksem Glitch: demonstracja i kod
- @EvroMalarkey z HTML/CSS/JS: prezentacja i kod