Ćwiczenia z programowania: tworzenie komponentu Sidenav

Z tego ćwiczenia w Codelabs dowiesz się, jak utworzyć elastyczny komponent układu wysuwanego bocznego panelu nawigacji w internecie. Tworzymy komponent na bieżąco. Zacznijmy od HTML, potem CSS, a potem JavaScript.

Przeczytaj mój post na blogu o tworzeniu komponentu Sidenav, aby dowiedzieć się więcej o funkcjach platformy internetowej CSS wybranych do tworzenia tego komponentu.

Konfiguracja

  1. Aby umożliwić edytowanie projektu, kliknij Zremiksuj do edycji.
  2. Otwórz pokój app/index.html.

HTML

Najpierw opanuj podstawy konfiguracji kodu HTML, aby przygotować treść i kilka pól do wykorzystania.

Upuść ten kod HTML w tagu <body>.

<aside></aside>
<main></main>

Element <aside> zawiera menu nawigacyjne jako element uzupełniający <main>, który zawiera główną treść strony.

Następnie uzupełnimy te elementy semantyczną pozostałą częścią strony.

W elemencie <aside> dodaj element nawigacyjny, kilka linków nawigacyjnych i link zamykający.

<aside>
  <nav>
    <h4>My</h4>
    <a href="#">Dashboard</a>
    <a href="#">Profile</a>
    <a href="#">Preferences</a>
    <a href="#">Archive</a>

    <h4>Settings</h4>
    <a href="#">Accessibility</a>
    <a href="#">Theme</a>
    <a href="#">Admin</a>
  </nav>

  <a href="#"></a>
</aside>

Linki świetnie sprawdzają się w elementach <nav>, a elementy <nav> – na paskach bocznych <aside>. Możemy jednak wprowadzić jeszcze więcej ulepszeń.

W elemencie main content dodaj nagłówek i artykuł, które mają semantycznie uwzględniać treść układu.

<main>
  <header>
    <a href="#sidenav-open" class="hamburger">
      <svg viewBox="0 0 50 40">
        <line x1="0" x2="100%" y1="10%" y2="10%" />
        <line x1="0" x2="100%" y1="50%" y2="50%" />
        <line x1="0" x2="100%" y1="90%" y2="90%" />
      </svg>
    </a>
    <h1>Site Title</h1>
  </header>

  <article>
    {put some placeholder content here}
  </article>
</main>

W nagłówku znajduje się otwarty link do menu. Na boku znajduje się przycisk zamykania. Wkrótce zaczniemy pokazywać i ukrywać elementy na podstawie rozmiaru widocznego obszaru.

W elemencie <article> wklejyliśmy zdanie tymczasowe. Zastąp „” własnymi rzeczami lub wklej lorem poniżej:

<h2>Totam Header</h2>
<p>Lorem ipsum dolor, sit amet consectetur adipisicing elit. Cum consectetur, necessitatibus velit officia ut impedit veritatis temporibus soluta? Totam odit cupiditate facilis nisi sunt hic necessitatibus voluptatem nihil doloribus! Enim.</p>
<p>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Fugit rerum, amet odio explicabo voluptas eos cum libero, ex esse quasi optio incidunt soluta eligendi labore error corrupti! Dolore, cupiditate porro.</p>

<h3>Subhead Totam Odit</h3>
<p>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Fugit rerum, amet odio explicabo voluptas eos cum libero, ex esse quasi optio incidunt soluta eligendi labore error corrupti! Dolore, cupiditate porro.</p>
<p>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Fugit rerum, amet odio explicabo voluptas eos cum libero, ex esse quasi optio incidunt soluta eligendi labore error corrupti! Dolore, cupiditate porro.</p>

<h3>Subhead</h3>
<p>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Fugit rerum, amet odio explicabo voluptas eos cum libero, ex esse quasi optio incidunt soluta eligendi labore error corrupti! Dolore, cupiditate porro.</p>
<p>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Fugit rerum, amet odio explicabo voluptas eos cum libero, ex esse quasi optio incidunt soluta eligendi labore error corrupti! Dolore, cupiditate porro.</p>

To właśnie ta zawartość i jej długość sprawiają, że strony można przewijać, gdy przekracza on wysokość widocznego obszaru.

Na razie dodaliśmy dodatkowy element z nawigacją, linkami i możliwością zamknięcia panelu bocznego. Dodałeś też nagłówek, sposób otwierania panelu bocznego i artykuł do głównego elementu. Już sama nazwa to jasna, semantyczna i ponadczasowa. Możemy jednak sprawić, by była bardziej przejrzysta i przejrzysta. Link otwarty w panelu bocznym może być wyraźniejszy.

Dodaj atrybuty title i aria-label do elementu linku otwartego w nagłówku:

<a href="#sidenav-open" class="hamburger">
<a href="#sidenav-open" title="Open Menu" aria-label="Open Menu" class="hamburger">

Można wyraźnie oznaczyć otwartą ikonę SVG. Dodaj te atrybuty do SVG w elemencie Open link (otwarty link):

<svg viewBox="0 0 50 40">
<svg viewBox="0 0 50 40" role="presentation" focusable="false" aria-label="trigram for heaven symbol">

Link zamykający w bocznym panelu nawigacyjnym może być wyraźniejszy. Dodaj atrybuty title i aria-label do elementu zamykającego link na pasku bocznym:

<a href="#"></a>
<a href="#" title="Close Menu" aria-label="Close Menu"></a>

CSS

Czas rozmieścić elementy. Główny element zawartości i nawigacja boczny są bezpośrednimi elementami podrzędnymi tagu <body>, więc warto zacząć od nich.

Dodaj ten kod CSS do elementu css/sidenav.css, aby element <body> określał elementy podrzędne.

body {
  display: grid;
  grid: [stack] 1fr / min-content [stack] 1fr;

  @media (max-width: 540px) {
    & > :matches(aside, main) {
      grid-area: stack;
    }
  }
}

Zasadniczo ten układ ma na celu utworzenie nazwanego wiersza stack, w którym znajdują się wszystkie elementy, oraz 2 kolumny w tym wierszu, z których druga również ma nazwę stack. Rozmiar pierwszej kolumny powinien być dostosowany do minimalnych wymagań związanych z treścią, a druga może zająć pozostałe. Następnie, jeśli widoczny obszar ma ograniczony widoczny obszar o wymiarach 540px lub mniej, umieść panel boczny i główne elementy zawartości w tym samym wierszu i kolumnie, co spowoduje, że będą się one na siebie nakładać w siatce 1 x 1.

Dzięki tej funkcji elastycznego stosowania można teraz wykorzystać stan paska adresu URL, aby przełączać widoczność i styl przejścia panelu bocznego.

Zaktualizuj element <aside> z powrotem w app/index.html:

<aside>
<aside id="sidenav-open">

Dzięki temu CSS może dopasować element i skrót adresu URL do siebie. Jest to ważne w przypadku korzystania z usługi :target. Teraz identyfikator elementu może pasować do skrótu adresu URL, który ustawimy w tagach <a>.

Aby ułatwić kierowanie na JavaScript, dodaj identyfikatory kluczowych elementów, które kontrolują panel boczny. Najpierw dodaj identyfikator do otwartego linku na pasku bocznym:

<a href="#sidenav-open" class="hamburger" title="Open Menu" aria-label="Open Menu">
<a href="#sidenav-open" id="sidenav-button" class="hamburger" title="Open Menu" aria-label="Open Menu">

Następnie dodaj identyfikator do linku zamykającego w bocznym panelu nawigacyjnym:

<a href="#" title="Close Menu" aria-label="Close Menu"></a>
<a href="#" id="sidenav-close" title="Close Menu" aria-label="Close Menu"></a>

To kończy elastyczny układ warstwowy <body> makra i łączy nas z paskiem adresu URL. Kontynuujmy!

<aside> również ma schludny układ. Ma 2 elementy podrzędne: element <nav>, który wysuwa się jak papier, i zamykający element linku <a>, którego adres URL musi mieć wartość #. Link jest niewidoczny z prawej strony wysuwanego panelu nawigacyjnego, dzięki czemu użytkownicy mogą „kliknąć” komponent wizualny, aby go zamknąć.

Dodaj do pliku css/sidenav.css ten kod CSS:

#sidenav-open {
  display: grid;
  grid-template-columns: [nav] 2fr [escape] 1fr;
}

Słyszałem, że format i nazwy są bardzo fajnym elementem.

Następnie muszę warunkowo nałożyć główną treść i utrwalić położenie w dowolnym momencie przewijania dokumentu. Świetna robota dla użytkownika position: sticky i overscroll-behavior.

Dodaj te style paska bocznego:

#sidenav-open {
  display: grid;
  grid-template-columns: [nav] 2fr [escape] 1fr;

  @media (max-width: 540px) {
    position: sticky;
    top: 0;
    max-height: 100vh;
    overflow: hidden auto;
    overscroll-behavior: contain;

    visibility: hidden; /* not keyboard accessible when closed */
  }
}

Dzięki tym stylom nawigator boczny będzie mieć wysokość widocznego obszaru, będzie przewijał się w pionie i zawiera elementy przewijania. Co bardzo ważne, ukrywa element. Domyślnie, jeśli widoczny obszar ma wartość 540px lub mniejszą, ukrywaj ten panel boczny. Chyba że

Dodaj pseudoselektor :target do elementu #sidenav-open:

#sidenav-open {

  @media (max-width: 540px) {

    &:target {
      visibility: visible;
    }
  }
}

Jeśli identyfikator tego elementu i paska adresu URL są takie same, ustaw visibility na visible. Po przewinięciu strony otwórz menu boczne lub spróbuj przewinąć stronę, gdy otwarty jest boczny panel nawigacyjny. Jak myślisz?

Na dole strony app/sidenav.css dodaj ten kod CSS:

#sidenav-button,
#sidenav-close {
  -webkit-tap-highlight-color: transparent;
  -webkit-touch-callout: none;
  user-select: none;
  touch-action: manipulation;

  @media (min-width: 540px) {
    display: none;
  }
}

Style te są kierowane na przyciski otwierania i zamykania, określają style dotknięcia i dotyku, a także ukrywają je, jeśli widoczny obszar jest większy niż 540px.

Aby dodać urozmaicenie, dodajmy przekształcenia CSS z uwzględnieniem ułatwień dostępu. Dodaj do pliku css/sidenav.css ten kod CSS:

#sidenav-open {
  --easeOutExpo: cubic-bezier(0.16, 1, 0.3, 1);
  --duration: .6s;

  ...

  @media (max-width: 540px) {
    ...

    transform: translateX(-110vw);
    will-change: transform;
    transition:
      transform var(--duration) var(--easeOutExpo),
      visibility 0s linear var(--duration);

    &:target {
      visibility: visible;
      transform: translateX(0);
      transition: transform var(--duration) var(--easeOutExpo);
    }
  }

  @media (prefers-reduced-motion: reduce) {
    --duration: 1ms;
  }
}
Demonstracja interakcji z czasem trwania i bez niego na podstawie zapytania o media „preferuje zmniejszony ruch”.

Dodaj fragmenty kodu JavaScript

Klawisz Escape powinien zamykać menu. Dodaj ten plik JS do pliku js/index.js:

const sidenav = document.querySelector('#sidenav-open');

sidenav.addEventListener('keyup', e => {
  if (e.code === 'Escape') {
    document.location.hash = '';
  }
});

Wykrywa kluczowe zdarzenie w elemencie bocznym panelu nawigacyjnego. W przypadku wartości Escape hasz adresu URL jest pusty, dzięki czemu panel boczny przejdzie w jedną stronę.

Kolejnym elementem UX JS jest zarządzanie koncentracją. Aby ułatwić otwieranie i zamykanie, czekam, aż panel boczny zakończy przejście, a potem porównuje go z hashtagiem adresu URL, aby sprawdzić, czy jest w polu adresu. Następnie używam JavaScriptu do ustawiania zaznaczenia przycisku na tym, który został właśnie naciśnięty.

Dodaj do pliku js/index.js ten kod JavaScript:

const closenav = document.querySelector('#sidenav-close');
const opennav = document.querySelector('#sidenav-button');

sidenav.addEventListener('transitionend', e => {
  if (e.propertyName !== 'transform') {
    return;
  }

  const isOpen = document.location.hash === '#sidenav-open';

  isOpen
    ? closenav.focus()
    : opennav.focus();
});

Wypróbuj

  • Aby wyświetlić podgląd strony, kliknij Wyświetl aplikację, a potem Pełny ekran pełny ekran.

Podsumowanie

To podsumowanie naszych potrzeb związanych z tym komponentem. Możesz go wykorzystać, używać stanu JavaScript zamiast adresu URL i ogólnie dostosować go do swoich potrzeb. Zawsze można dodać kolejne przypadki użycia do omówienia.

Otwórz css/brandnav.css, aby zobaczyć style niezwiązane z układem, które zostały zastosowane do tego komponentu. Zestaw funkcji, na którym się skupiam, nie jest ważny. Liczyłem, że oddzielenie stylów od układu zachęca do kopiowania i wklejania. Teraz możesz się tam uczyć.

Jak utworzyć wysuwane komponenty panelu bocznego? Czy masz więcej niż jedno, np. jedną po obu stronach? Chętnie przedstawię Twoje rozwiązanie w filmie w YouTube. Pamiętaj, aby napisać do mnie tweeta lub podać swój kod w komentarzu w YouTube. Przyda się on wszystkim użytkownikom.