Tworzenie komponentu menu nawigacyjnego

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 przedstawię sposoby tworzenia komponentów menu nawigacyjnego. Wypróbuj wersję demonstracyjną.

Demonstracja
.

Jeśli wolisz film, oto wersja tego posta w YouTube:

Omówienie

Komponent menu nawigacyjnego pokazuje: w którym miejscu w hierarchii witryny znajduje się użytkownik. Nazwa pochodzi od Hansela Gretel, która zrezygnowała menu nawigacyjne za nimi w ciemnym lesie, w którym udało im się dotrzeć do domu przez śledzenie okruchów wstecz.

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.

Wrażenia użytkowników w tle

W filmie demonstracyjnym komponentu powyżej kategorie zastępcze to gatunki: gier wideo. Szlak ten tworzysz, korzystając z tej ścieżki: home » rpg » indie » on sale, jak pokazano poniżej.

Ten komponent menu nawigacyjnego powinien umożliwiać użytkownikom poruszanie się hierarchia informacji; oraz szybkie wybieranie stron. dokładności.

Architektura informacji

Warto myśleć o kolekcjach i przedmiotach.

Kolekcje

Kolekcja to tablica 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 przedmiot i prawidłowy atrybut kolekcji. Gdy jest to produkt, użytkownik jest na tej stronie kolekcji. Przykład: znajduje się na stronie RPG, która zawiera listę gier RPG, dodatkowe podkategorie AAA, Indie i Samodzielne.

W kontekście informatycznym ten komponent menu nawigacyjnego reprezentuje wielowymiarowe tablica:

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ć własną architekturę informacji, co spowoduje 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ę dobór znaczników i ich wpływu na ogólny komponent.

Schemat jasny i ciemny

<meta name="color-scheme" content="dark light">

Metatag color-scheme w powyższym informuje przeglądarkę, że ta strona chce korzystać z przeglądarki jasnej i ciemnej stylów. Przykładowe menu nawigacyjne nie zawiera kodu CSS dla tych schematów kolorów, W menu nawigacyjnym zostaną użyte domyślne kolory podane przez przeglądarkę.

<nav class="breadcrumbs" role="navigation"></nav>

Użycie funkcji Element <nav> do nawigacji w witrynie, która ma domyślnie przypisaną rolę ARIA nawigacji. Podczas testów zauważyliśmy, że atrybut role zmienił sposób Czytnik ekranu wszedł w interakcję z elementem, a następnie ogłoszono, że nawigacji, więc postanowiłem to dodać.

Ikony

Gdy ikona powtarza się na stronie, plik SVG Element <use> oznacza, że można zdefiniować element path raz i użyć go we wszystkich instancjach . 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, umieszcza informacje o ikonach w pamięci i Pozostała część strony zawiera odniesienie do identyfikatora w celu dodatkowych zastosowań. kliknij ikonę w taki sposób:

<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>

Narzędzia deweloperskie pokazujące wyrenderowany element użycia SVG.

Zdefiniuj raz, użyj tyle razy, ile chcesz, przy minimalnym wpływie na wydajność strony i elastycznym stylem. Zwróć uwagę, że do elementu SVG dodano aria-hidden="true". Nie przydają się one osobom przeglądającym, którzy tylko słyszą treść, ukrywając powstrzymuje ich od dodawania zbędnego szumu.

Tutaj tradycyjne menu nawigacyjne i elementy tego komponentu się różnią. Normalnie byłby to tylko link <a>, ale dodałem UX przemierzania za pomocą zamaskowany wybór. Klasa .crumb odpowiada za rozmieszczenie linku i ikonę, a .crumbicon odpowiada za układanie ikony w stosy i zaznaczanie elementu. Nazywam go „dzielonym linkiem”, ponieważ jego funkcje są bardzo podobny do podzielonego przycisku, lecz także do nawigacji.

<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 title do elementu <select> jest przydatne na ekranie użytkowników czytnika, informując ich o działaniu przycisku. Pamiętaj jednak, zapewnia taką samą pomoc wszystkim pozostałym użytkownikom. na iPadzie. Jeden atrybut zapewnia wielu użytkownikom kontekst dla przycisku.

Zrzut ekranu przedstawiający najechany niewidoczny element wyboru i jego
kontekstowa etykietka.

Dekoracje separatorów

<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). Daję każde aria-hidden="true", ponieważ są dekoracyjne, a nie dekoracyjne o czym musi pamiętać czytnik ekranu.

Właściwość gap (opisana poniżej) sprawia, że odstępy między nimi są proste.

Style

Ponieważ w kolorach są używane kolory systemowe, są to głównie luki i stosy stylów.

Kierunek i przepływ układu

Narzędzia deweloperskie pokazujące wyrównanie menu nawigacyjnego z nakładką Flexbox
funkcji.

Główny element nawigacyjny nav.breadcrumbs ustawia właściwość niestandardową o zakresie do wykorzystania przez dzieci i w inny sposób tworzy układ poziomy, wyrównany w pionie układ. Dzięki temu elementy składowe, separatory i ikony są wyrównane.

.breadcrumbs {
  --nav-gap: 2ch;

  display: flex;
  align-items: center;
  gap: var(--nav-gap);
  padding: calc(var(--nav-gap) / 2);
}

1 menu nawigacyjne wyświetlane pionowo z nakładkami Flexbox.

Każdy element .crumb tworzy też poziomy układ wyrównany w pionie z luka, ale specjalnie kieruje swoje elementy podrzędne i określa styl white-space: nowrap Ma to kluczowe znaczenie w przypadku menu nawigacyjnego zawierających wiele słów, ponieważ by mieć rozwiązanie wielowierszowe. W dalszej części tego posta dodamy style do obsługi poziome przepełnienie spowodowane tą właściwością 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;
    }
  }
}

Dodano aria-current="page", aby link do bieżącej strony wyróżniał się na tle odpoczynek. Użytkownicy czytników ekranu będą mieć nie tylko jasny wskaźnik, że link na bieżącej stronie zmieniliśmy wygląd elementu, aby pomóc osobom widzącym mają podobne wrażenia.

Komponent .crumbicon używa siatki do nakładania ikony SVG z „niemal niewidoczne" <select>.

Siatka z Narzędziami deweloperskimi z nałożonym przyciskiem, tam gdzie wiersz i kolumna są jednocześnie
stos o nazwie.

.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 na utrzymanie wbudowanych funkcji.

.disguised-select {
  inline-size: 100%;
  block-size: 100%;
  opacity: .01;
  font-size: min(100%, 16px); /* Defaults to 16px; fixes iOS zoom */
}

Rozwijany

Menu nawigacyjne powinno reprezentować bardzo długi szlak. Jestem zwolennikiem że w odpowiednich przypadkach przesunęły się one poza ekran. .

.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 nadmiarowe umożliwiają skonfigurowanie takiego interfejsu użytkownika:

  • Przewijanie poziome z ograniczeniem przewijania.
  • Dopełnienie przewijania w poziomie.
  • Jeden punkt przyciągania do ostatniego elementu. Oznacza to, że podczas wczytywania strony pierwszy elementy składowe zostały przyciągnięte i widoczne.
  • Usuwa punkt przyciągania z przeglądarki Safari, który ma problemy z orientacją w poziomie. kombinacje efektu przewijania i przyciągania.

Zapytania o multimedia

Subtelną korektą w mniejszych widocznych obszarach jest ukrycie ekranu głównego. label, opuszczając tylko ikonę:

@media (width <= 480px) {
  .breadcrumbs .home-label {
    display: none;
  }
}

Obok menu nawigacyjnego z etykietą „Home” lub bez niej, w przypadku:
porównanie.

Ułatwienia dostępu

Ruch

W tym komponencie nie ma dużo ruchu, ale jeśli zawiniesz przejście w mechanizmie kontroli prefers-reduced-motion może zapobiec niepożądanym 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 menu nawigacyjne, URL musi zostać zaktualizowany, wyświetli odpowiednią stronę. Po drugie, aby znormalizować wrażenia użytkownika, upewnij się, podczas przeglądania strony <select> nie występują żadne nieoczekiwane nawigację .

Dwa kluczowe wskaźniki wygody użytkowników, które mają być obsługiwane przez JavaScript: zmienił się i chętniej <select> zapobiega uruchamianiu zdarzeń zmiany.

Zastosowanie: <select> wymaga zapobiegania zdarzeniom . W Windows Edge, a zapewne w innych przeglądarkach, wybierz changed jest wywoływane, gdy użytkownik przegląda opcje za pomocą klawiatury. Dlatego czyli „chętny”, ponieważ użytkownik wybrał tylko pseudoopcję, np. najechanie kursorem lub zaznaczyć, zanim jeszcze potwierdził(a) swój wybór za pomocą: 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.

Lepszy zmieniony <select>

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? 🙂

Stosujmy różne podejścia i poznajmy sposoby budowania obecności w internecie. Utwórz wersję demonstracyjną, a potem dodaj linki do funkcji tweetuj mi. znajdziesz poniżej w sekcji z remiksami na karcie Społeczność.

Remiksy utworzone przez społeczność