Codelab: Sidenav-Komponente erstellen

In diesem Codelab erfahren Sie, wie Sie eine responsive Komponente für das ausblendbare Layout in der seitlichen Navigationsleiste im Web erstellen. Wir erstellen die Komponente und beginnen mit HTML, CSS und JavaScript.

In meinem Blogpost zum Erstellen einer Sidenav-Komponente erfahren Sie mehr über die CSS-Webplattformfunktionen, die zum Erstellen dieser Komponente ausgewählt wurden.

Einrichtung

  1. Klicke auf Zu bearbeitende Remixe, damit das Projekt bearbeitet werden kann.
  2. Öffnen Sie app/index.html.

HTML

Zunächst müssen Sie sich mit den Grundlagen der HTML-Einrichtung vertraut machen, sodass Sie Inhalte und einige Felder haben, mit denen Sie arbeiten können.

Fügen Sie den folgenden HTML-Code in das <body>-Tag ein.

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

Das <aside> enthält das Navigationsmenü als ergänzendes Element zu <main>, das den primären Seiteninhalt enthält.

Als Nächstes füllen wir diese semantischen Elemente mit dem restlichen Seiteninhalt aus.

Fügen Sie ein Navigationselement sowie einige Navigationslinks und einen Link zum Schließen innerhalb des <aside>-Elements hinzu.

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

Links eignen sich hervorragend innerhalb von <nav>-Elementen und <nav>-Elemente eignen sich hervorragend für <aside>-Seitenleisten. Es gibt jedoch noch mehr, was wir verbessern können.

Fügen Sie im Hauptinhaltselement eine Überschrift und einen Artikel für den Layoutinhalt hinzu.

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

In der Kopfzeile wird der Link zum Öffnen des Menüs angezeigt. Die Seite enthält die Schaltfläche „Schließen“. Bald werden Elemente je nach Größe des Darstellungsbereichs ein- und ausgeblendet.

Im <article>-Element haben wir einen Platzhaltersatz eingefügt. Ersetzen Sie „`` durch einen eigenen Text oder fügen Sie den unten angegebenen Platzhalter ein:

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

Dieser Inhalt sowie seine Länge sorgen dafür, dass die Seite scrollbar ist, wenn sie die Höhe des Darstellungsbereichs überschreitet.

Bisher haben Sie ein Aside-Element mit einer Navigation, Links und einer Möglichkeit zum Schließen des Sidenav-Elements hinzugefügt. Außerdem haben Sie eine Kopfzeile hinzugefügt, eine Möglichkeit zum Öffnen der seitlichen Navigationsleiste und einen Artikel zum Hauptelement. Sie ist klar, semantisch und ziemlich zeitlos, aber wir können sie für alle klarer gestalten. Der offene Link in der seitlichen Navigationsleiste könnte deutlicher gekennzeichnet sein.

Fügen Sie dem Linkelement zum Öffnen der Kopfzeile die Attribute title und aria-label hinzu:

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

Das geöffnete SVG-Symbol könnte ebenfalls deutlicher gekennzeichnet sein. Fügen Sie der SVG im offenen Linkelement die folgenden Attribute hinzu:

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

Der Link zum Schließen in der seitlichen Navigationsleiste könnte deutlicher gekennzeichnet sein. Fügen Sie dem Linkelement zum Schließen der seitlichen Navigationsleiste die Attribute title und aria-label hinzu:

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

CSS

Zeit, die Elemente anzuordnen. Hauptinhalt und Sidenav sind dem <body>-Tag direkt untergeordnet, daher ist das ein guter Anfang.

Fügen Sie den folgenden CSS-Code in css/sidenav.css ein, damit das <body>-Element das Layout der untergeordneten Elemente festlegt.

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

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

Dieses Layout besagt im Wesentlichen: Erstellen Sie eine benannte Zeile stack mit allem darin enthaltenen Inhalt und zwei Spalten in dieser Zeile, die zweite heißt stack. Die Größe der ersten Spalte sollte den minimalen inhaltlichen Anforderungen entsprechen, während die zweite Spalte den Rest einnimmt. Wenn sich dann in einem eingeschränkten Darstellungsbereich von 540px oder weniger die Elemente für die Seitennavigation und den Hauptinhalt befinden, platzieren Sie sie in derselben Zeile und Spalte, sodass sie in einem 1x1-Raster übereinander liegen.

Mit dieser responsiven Stapelfunktion als Grundlage können wir jetzt den Status der URL-Leiste nutzen, um den Sichtbarkeits- und Übergangsstil der seitlichen Navigationsleiste umzuschalten.

Aktualisieren Sie das <aside>-Element wieder in app/index.html:

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

Dadurch kann CSS zwischen Elementen und URL-Hashwerten. Das ist für die Verwendung von :target wichtig. Jetzt entspricht die ID des Elements dem URL-Hash, den wir mit den <a>-Tags festlegen.

Für eine einfachere JavaScript-Ausrichtung können Sie außerdem IDs für wichtige Elemente hinzufügen, mit denen die seitliche Navigationsleiste gesteuert wird. Fügen Sie zuerst dem Link für die seitliche Navigationsleiste eine ID hinzu:

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

Fügen Sie als Nächstes dem Link zum Schließen der seitlichen Navigationsleiste eine ID hinzu:

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

Damit wird das Makro-<body> responsive Stapellayout abgeschlossen und wir sind in der URL-Leiste verbunden. Weiter geht‘s!

<aside> hat auch ein übersichtliches Layout. Es hat zwei untergeordnete Elemente: <nav>, d. h. eine papierähnliche Komponente, die herausgeschoben wird, und ein schließendes <a>-Linkelement, mit dem die URL auf # festgelegt wird. Der Link ist rechts neben dem Papier-Navigationsleiste nicht sichtbar. Über ihn können Nutzer die visuelle Komponente „ausklicken“, um sie zu schließen.

Fügen Sie css/sidenav.css das folgende CSS hinzu:

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

Ich fand das Seitenverhältnis und die Namen sehr schön, denn das Raster kann glänzen und Designschaffenden mehr Kontrolle

Als Nächstes muss ich den Hauptinhalt bedingt einblenden und meine Position beim Scrollen durch das Dokument beibehalten. Das ist eine gute Arbeit für position: sticky und einige overscroll-behavior.

Fügen Sie die folgenden Stile für die seitliche Navigationsleiste hinzu:

#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 */
  }
}

Mit diesen Stilen wird sichergestellt, dass die seitliche Navigationsleiste der Höhe des Darstellungsbereichs entspricht, vertikal scrollt und die Scrollbewegung enthält. Sehr wichtig ist, dass das Element ausgeblendet wird. Wenn der Darstellungsbereich 540px oder kleiner ist, wird diese seitliche Navigationsleiste standardmäßig ausgeblendet. Es sei denn!

Fügen Sie dem Element #sidenav-open einen :target-Pseudoselektor hinzu:

#sidenav-open {

  @media (max-width: 540px) {

    &:target {
      visibility: visible;
    }
  }
}

Wenn die ID dieses Elements und der URL-Leiste identisch sind, setzen Sie visibility auf visible. Öffnen Sie nach dem Scrollen das seitliche Menü oder scrollen Sie auf der Seite, während die seitliche Navigationsleiste geöffnet ist. Was ist Ihre Meinung dazu?

Fügen Sie am Ende von app/sidenav.css den folgenden CSS-Code ein:

#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;
  }
}

Diese Stile sind auf unsere Schaltflächen zum Öffnen und Schließen ausgerichtet und geben die Stile für das Tippen und Tippen an. Außerdem werden sie ausgeblendet, wenn Darstellungsbereiche mindestens 540px sind.

Fügen wir CSS-Transformationen mit respektvoller Barrierefreiheit hinzu. Fügen Sie css/sidenav.css das folgende CSS hinzu:

#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;
  }
}
Demo der Interaktion mit und ohne Anwendung der Dauer, basierend auf der Medienabfrage „prefers-Reduced-motion“.

Verteilen Sie etwas JavaScript

Mit der Taste Escape sollte das Menü geschlossen werden. Füge dieses JS zu js/index.js hinzu:

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

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

Damit wird auf ein Schlüsselereignis für das Element „Sidenav“ gewartet. Wenn es Escape lautet, wird der URL-Hash auf leer gesetzt, wodurch die Seitenleiste ersetzt wird.

Der nächste Teil von UX-JS ist Fokusmanagement. Ich möchte das Öffnen und Schließen vereinfachen. Also warte ich, bis die Sidenav-Funktion einen Übergang irgendeiner Form ausgeführt hat, und vergleiche sie dann mit dem URL-Hash, um festzustellen, ob sie vorhanden ist oder nicht. Mit JavaScript lege ich den Fokus auf die Schaltfläche, auf die gerade geklickt wurde.

Fügen Sie js/index.js den folgenden JavaScript-Code hinzu:

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();
});

Ausprobieren

  • Um die Website als Vorschau anzusehen, wählen Sie App ansehen und dann Vollbild Vollbild aus.

Fazit

Ich bin nun zum Abschluss für die Anforderungen, die ich an die Komponente hatte. Sie können darauf aufbauen, sie mit dem JavaScript-Status statt der URL steuern und ganz allgemein anpassen. Sie können immer mehr hinzufügen oder weitere Anwendungsfälle abdecken.

Öffnen Sie css/brandnav.css, um die nicht mit dem Layout zusammenhängenden Stile zu sehen, die ich auf diese Komponente angewendet habe. für die Funktionen, auf die ich mich konzentrierte, nicht wichtig, und ich hoffte, dass das Trennen der Stile vom Layout das Kopieren und Einfügen fördern würde. Dort könnten Sie noch mehr lernen!

Wie erstellen Sie ausblendbare Komponenten für die seitliche Navigationsleiste? Hast du jemals mehr als eine, zum Beispiel eine auf beiden Seiten? Ich würde deine Lösung gern in einem YouTube-Video vorstellen. Tweete uns an oder kommentiere mit deinem Code auf YouTube. Das hilft allen weiter.