Podstawowe informacje o tworzeniu elastycznych i łatwo dostępnych komponentów menu nawigacyjnego, które ułatwią użytkownikom poruszanie się po witrynie.
W tym poście chcę podzielić się z Tobą sposobem tworzenia komponentów ścieżki nawigacyjnej. Wypróbuj wersję demonstracyjną.
Jeśli wolisz film, oto wersja tego posta w YouTube:
Omówienie
Komponent ścieżki menu nawigacyjnego wskazuje, w którym miejscu w hierarchii witryny znajduje się użytkownik. Nazwa pochodzi od Jaś i Małgosia, którzy w ciemnym lesie zostawili za sobą okruchy chleba, dzięki czemu mogli odnaleźć drogę do domu, podążając za tymi okruchami.
Menu nawigacyjne w tym poście jest niestandardowe
menu nawigacyjnego,
wygląda jak menu nawigacyjne. Zapewniają dodatkowe funkcje dzięki połączeniu elementów równorzędnych
bezpośrednio do nawigacji dzięki funkcji <select>
, dzięki czemu dostęp wielopoziomowy
jak to tylko możliwe.
Tłogowisko
W filmie demonstracyjnym komponentu powyżej kategorie zastępcze to gatunki:
gier wideo. Ścieżka ta jest tworzona po wybraniu tej ścieżki: home »
rpg » indie » on sale
, jak pokazano poniżej.
Ten element ścieżki nawigacyjnej powinien umożliwiać użytkownikom poruszanie się po tej hierarchii informacji, szybkie przechodzenie między gałęziami i dokładne wybieranie stron.
Architektura informacji
Warto myśleć o kolekcjach i przedmiotach.
Kolekcje
Kolekcja to zbiór opcji do wyboru. Na stronie głównej usługi to prototyp menu nawigacyjnego. Są to kolekcje FPS, RPG, brawler robot do lochów, sport i łamigłówki.
Elementy
Gra wideo to przedmiot, a konkretna kolekcja może być również przedmiotem, jeśli reprezentuje kolejną kolekcję. Na przykład RPG to element i poprawna kolekcja. Gdy jest to element, użytkownik jest na tej stronie kolekcji. Na przykład na stronie z grami RPG, która zawiera listę gier RPG, w tym dodatkowe podkategorie AAA, Indie i Self Published.
W terminologii informatycznej ten element ścieżki stanowi wielowymiarową tablicę:
const rawBreadcrumbData = {
"FPS": {...},
"RPG": {
"AAA": {...},
"indie": {
"new": {...},
"on sale": {...},
"under 5": {...},
},
"self published": {...},
},
"brawler": {...},
"dungeon crawler": {...},
"sports": {...},
"puzzle": {...},
}
Twoja aplikacja lub witryna będzie mieć niestandardową architekturę informacji, w wielowymiarowej tablicy, ale mam nadzieję, że koncepcja strony docelowej kolekcji stron i przemierzania hierarchii mogą być również uwzględniane w menu nawigacyjnym.
Układy
Markup
Dobre komponenty zaczynają się od odpowiedniego kodu HTML. W następnej sekcji omówię wybrane przeze mnie opcje znaczników i ich wpływ na cały komponent.
Schemat jasny i ciemny
<meta name="color-scheme" content="dark light">
Metatag color-scheme
w powyższym
informuje przeglądarkę, że strona chce korzystać z przeglądarki jasnej i ciemnej
stylów. Przykładowe elementy nawigacyjne nie zawierają kodu CSS dla tych schematów kolorów,
dlatego będą używać domyślnych kolorów udostępnionych przez przeglądarkę.
Element nawigacji
<nav class="breadcrumbs" role="navigation"></nav>
Użycie parametru
Element <nav>
do nawigacji w witrynie, która ma domyślnie przypisaną rolę ARIA
nawigacji.
Podczas testów zauważyliśmy, że atrybut role
zmienia sposób interakcji czytnika ekranu z elementem. W fakcie był on ogłaszany jako element nawigacji, dlatego zdecydowaliśmy się go dodać.
Ikony
Gdy ikona jest powtarzana na stronie, element SVG
<use>
oznacza, że możesz zdefiniować path
raz i używać go we wszystkich wystąpieniach ikony. Zapobiega to powtarzaniu informacji o tej samej ścieżce, przez co
większe dokumenty i ryzyko niespójności ścieżek.
Aby skorzystać z tej metody, dodaj do strony ukryty element SVG i zapakuj ikony
w elemencie <symbol>
o unikalnym identyfikatorze:
<svg style="display: none;">
<symbol id="icon-home">
<title>A home icon</title>
<path d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6"/>
</symbol>
<symbol id="icon-dropdown-arrow">
<title>A down arrow</title>
<path d="M19 9l-7 7-7-7"/>
</symbol>
</svg>
Przeglądarka odczytuje kod HTML SVG, zapisze informacje o ikonie w pamięci i przejdzie do dalszej części strony, która odwołuje się do identyfikatora ikony w celu jej dodatkowego użycia.
<svg viewBox="0 0 24 24" width="24" height="24" aria-hidden="true">
<use href="#icon-home" />
</svg>
<svg viewBox="0 0 24 24" width="24" height="24" aria-hidden="true">
<use href="#icon-dropdown-arrow" />
</svg>
Zdefiniuj raz, używaj tyle razy, ile chcesz, z minimalnym wpływem na wydajność strony i elastycznym stylizowaniem. Zwróć uwagę, że do elementu SVG dodano aria-hidden="true"
.
Ikony nie są przydatne dla osób, które przeglądają treści tylko przy użyciu dźwięku. Ukrywanie ich przed tymi użytkownikami zapobiega dodawaniu przez nich niepotrzebnego hałasu.
Podziel link .crumb
Właśnie w tym miejscu tradycyjne menu nawigacyjne różni się od tego w tym komponencie.
Zwykle jest to tylko link <a>
, ale dodałem interfejs użytkownika z ukrytym elementem select. Klasa .crumb
odpowiada za rozmieszczenie linku i
ikonę, a .crumbicon
odpowiada za układanie ikony w stosy i zaznaczanie
elementu. Nazwałem go „linkiem podzielonym”, ponieważ jego funkcje są bardzo podobne do przycisku podzielonego, ale służy do nawigacji po stronach.
<span class="crumb">
<a href="#sub-collection-b">Category B</a>
<span class="crumbicon">
<svg>...</svg>
<select class="disguised-select" title="Navigate to another category">
<option>Category A</option>
<option selected>Category B</option>
<option>Category C</option>
</select>
</span>
</span>
Link i niektóre opcje nie są wyjątkami, ale zwiększają funkcjonalność
proste menu nawigacyjne. Dodanie elementu title
do elementu <select>
jest przydatne dla użytkowników czytników ekranu, ponieważ dostarcza im informacji o działaniu przycisku. Jednak ta sama pomoc jest dostępna dla wszystkich użytkowników, a na iPadzie jest widoczna na pierwszym planie. Jeden atrybut zapewnia wielu użytkownikom kontekst dla przycisku.
Dekoracje separatora
<span class="crumb-separator" aria-hidden="true">→</span>
Użycie separatorów jest opcjonalne. Świetnie sprawdza się też dodanie tylko jednego z nich (zobacz trzeci przykład
powyżej). Następnie dodaję aria-hidden="true"
, ponieważ są one dekoracyjne i nie muszą być odczytywane przez czytnik ekranu.
Właściwość gap
, o której opowiemy w następnym punkcie, ułatwia prawidłowe rozmieszczanie tych elementów.
Style
Ponieważ kolory są kolorami systemowymi, w większości są to luki i zbiory stylów.
Kierunek i przepływ układu
Główny element nawigacji nav.breadcrumbs
ustawia ograniczoną właściwość niestandardową do użycia przez elementy podrzędne, a także określa układ poziomy z wyrównaniem pionowym. Dzięki temu elementy ścieżki, separatory i ikony będą wyrównane.
.breadcrumbs {
--nav-gap: 2ch;
display: flex;
align-items: center;
gap: var(--nav-gap);
padding: calc(var(--nav-gap) / 2);
}
Każdy element .crumb
tworzy też poziomy układ z niewielkim odstępem, ale kieruje się na elementy podrzędne linku i określa styl white-space: nowrap
. Jest to bardzo ważne w przypadku menu nawigacyjnego z wielu słów, ponieważ nie chcemy, aby zajmowało ono kilka wierszy. W dalszej części tego posta dodamy style, które umożliwią obsłużenie poziomego przepełnienia przez usługę white-space
.
.crumb {
display: inline-flex;
align-items: center;
gap: calc(var(--nav-gap) / 4);
& > a {
white-space: nowrap;
&[aria-current="page"] {
font-weight: bold;
}
}
}
Dodajemy aria-current="page"
, aby wyróżnić link do bieżącej strony na tle reszty. Użytkownicy czytników ekranu będą mieć wyraźny wskaźnik, że link prowadzi do bieżącej strony, ale także zmieniliśmy styl wizualny elementu, aby ułatwić korzystanie z niego użytkownikom ze wzrokiem.
Komponent .crumbicon
używa siatki do nakładania ikony SVG z „niemal
niewidoczne" <select>
.
.crumbicon {
--crumbicon-size: 3ch;
display: grid;
grid: [stack] var(--crumbicon-size) / [stack] var(--crumbicon-size);
place-items: center;
& > * {
grid-area: stack;
}
}
Element <select>
jest ostatni w DOM, więc znajduje się nad stosem,
i interaktywny. Dodaj styl opacity: .01
, aby element nadal mógł być użyteczny,
w rezultacie powstanie pole zaznaczenia, które idealnie pasuje do kształtu ikony.
To dobry sposób na dostosowanie wyglądu elementu <select>
podczas
i obsługuje
wbudowane funkcje.
.disguised-select {
inline-size: 100%;
block-size: 100%;
opacity: .01;
font-size: min(100%, 16px); /* Defaults to 16px; fixes iOS zoom */
}
Rozwijany
Ścieżka powinna być w stanie reprezentować bardzo długi ślad. Jestem zwolennikiem że w odpowiednich sytuacjach przesuną się poza ekran w poziomie. .
.breadcrumbs {
overflow-x: auto;
overscroll-behavior-x: contain;
scroll-snap-type: x proximity;
scroll-padding-inline: calc(var(--nav-gap) / 2);
& > .crumb:last-of-type {
scroll-snap-align: end;
}
@supports (-webkit-hyphens:none) { & {
scroll-snap-type: none;
}}
}
Style przepełnienia umożliwiają takie działanie:
- Przewijanie poziome z ograniczeniem przewijania.
- Dopełnienie przesunięcia poziomego.
- Jeden punkt dopasowania na ostatnim fragmencie ścieżki. Oznacza to, że po wczytaniu strony pierwszy elementCrumb wczytuje się w ramach widoku.
- Usunięcie punktu zazębiania z Safari, który ma problemy z kombinacją przewijania poziomego i punktów zazębiania.
Zapytania multimedialne
Subtelną korektą w mniejszych widocznych obszarach jest ukrycie ekranu głównego. label, opuszczając tylko ikonę:
@media (width <= 480px) {
.breadcrumbs .home-label {
display: none;
}
}
Ułatwienia dostępu
Ruch
W tym komponencie nie ma zbyt wielu ruchów, ale dzięki umieszczeniu przejścia w ramach kontroli prefers-reduced-motion
możemy zapobiec niechcianym ruchom.
@media (prefers-reduced-motion: no-preference) {
.crumbicon {
transition: box-shadow .2s ease;
}
}
Żaden inny styl nie wymaga zmiany. Efekty najechania kursorem i zaznaczenia są świetne.
i wartościowe bez transition
. Jeśli ruch jest prawidłowy, dodajemy subtelny
do interakcji.
JavaScript
Po pierwsze, niezależnie od typu routera używanego w witrynie lub aplikacji, gdy użytkownik zmieni informacje w śladach, adres URL musi zostać zaktualizowany, a użytkownik musi zobaczyć odpowiednią stronę. Po drugie, aby ujednolicić wrażenia użytkowników, zadbaj o to, aby nie było nieoczekiwanych przejść, gdy użytkownicy przeglądają <select>
opcje.
Dwa kluczowe wskaźniki wrażeń użytkownika, które mają być obsługiwane przez JavaScript:
zmienił się i chętniej <select>
ustawił blokadę uruchamiania zdarzenia zmiany.
Pośpieszna zapobieganie zdarzeniom jest konieczne ze względu na użycie elementu <select>
. W przeglądarce Edge na Windowsie (i prawdopodobnie też w innych przeglądarkach) zdarzenie select changed
wyzwala się, gdy użytkownik przegląda opcje za pomocą klawiatury. Dlatego nazywam je „niecierpliwe”, ponieważ użytkownik wybrał opcję tylko pozornie, np. przez najechanie kursorem lub skupienie się na niej, ale nie potwierdził wyboru za pomocą przycisku enter
ani click
. Pragniący
sprawia, że funkcja zmiany kategorii komponentu jest niedostępna, ponieważ
otwarcie pola wyboru i przeszukanie elementu spowoduje uruchomienie zdarzenia,
zmienić stronę, zanim użytkownik będzie gotowy.
Lepsze zdarzenie (<select>
) zostało zmienione
const crumbs = document.querySelectorAll('.breadcrumbs select')
const allowedKeys = new Set(['Tab', 'Enter', ' '])
const preventedKeys = new Set(['ArrowUp', 'ArrowDown'])
// watch crumbs for changes,
// ensures it's a full value change, not a user exploring options via keyboard
crumbs.forEach(nav => {
let ignoreChange = false
nav.addEventListener('change', e => {
if (ignoreChange) return
// it's actually changed!
})
nav.addEventListener('keydown', ({ key }) => {
if (preventedKeys.has(key))
ignoreChange = true
else if (allowedKeys.has(key))
ignoreChange = false
})
})
W tym celu należy zwracać uwagę na przypadki braku klawiatury w każdym <select>
i określić, czy naciśnięty klawisz to potwierdzenie nawigacji (Tab
lub
Enter
) lub nawigacji przestrzennej (ArrowUp
lub ArrowDown
). W związku z tym
determinacja, komponent może zdecydować, czy zaczekać, czy też zakończyć, gdy zdarzenie dla
Uruchomiono <select>
element.
Podsumowanie
Wiesz już, jak to zrobiłem. Jak Ty? 🙂
Zróżnicujemy nasze podejścia i poznamy wszystkie sposoby tworzenia stron internetowych. Utwórz wersję demonstracyjną, wyślij mi linki, a ja dodam je do sekcji z remiksami społeczności.
Remiksy społeczności
- Tux Solbakk jako komponent internetowy: demonstracja i kod