Komponente „Sidenav“ erstellen

Grundlegende Übersicht zum Erstellen einer responsiven Slide-Out-Side-Navigation

In diesem Beitrag möchte ich Ihnen zeigen, wie ich einen Prototyp einer Sidenav-Komponente für das Web erstellt habe, mit der ist responsiv, zustandsorientiert, unterstützt Tastaturnavigation, funktioniert mit und ohne JavaScript, und funktioniert browserübergreifend. Demo ansehen

Falls Sie Videos bevorzugen, finden Sie hier eine YouTube-Version dieses Beitrags:

Übersicht

Es ist nicht einfach, ein reaktionsschnelles Navigationssystem zu entwickeln. Einige nutzen eine Tastatur, einige verfügen über leistungsstarke Desktops, andere über ein kleines Mobilgerät. Alle Besucher sollten das Menü öffnen und schließen können.

<ph type="x-smartling-placeholder">
</ph> <ph type="x-smartling-placeholder"> <ph type="x-smartling-placeholder">
</ph> Demo für responsives Layout für Computer zu Mobilgeräten
<ph type="x-smartling-placeholder"> <ph type="x-smartling-placeholder">
</ph> Helles und dunkles Design für iOS und Android

Webtaktik

In dieser explorativen Datenanalyse habe ich einige wichtige Webplattformfunktionen kombiniert:

  1. Preisvergleichsportal :target
  2. CSS-Raster
  3. CSS-Transformationen
  4. CSS-Medienabfragen für Darstellungsbereich und Nutzereinstellungen
  5. JS für focus UX-Verbesserungen

Meine Lösung hat eine Seitenleiste und kann nur bei einem „Mobilgerät“ ein-/ausgeschaltet werden. Darstellungsbereich von 540px oder weniger. 540px ist unser Haltepunkt für den Wechsel zwischen dem interaktiven Layout für Mobilgeräte und dem statischen Desktop-Layout.

CSS-:target-Pseudoklasse

Bei einem <a>-Link wird der URL-Hash auf #sidenav-open und bei dem anderen auf einen leeren Link ('') festgelegt. Schließlich hat ein Element die id, die dem Hash entspricht:

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

Wenn Sie auf einen dieser Links klicken, ändert sich der Hash-Status der Seiten-URL. Dann zeige und blende mit einer Pseudoklasse das Sidenav ein und aus:

@media (max-width: 540px) {
  #sidenav-open {
    visibility: hidden;
  }

  #sidenav-open:target {
    visibility: visible;
  }
}

CSS-Raster

Früher habe ich nur die absolute oder feste Position verwendet. Sidenav-Layouts und -Komponenten. „Grid“ bietet mit seiner grid-area-Syntax können wir einer Zeile oder Spalte mehrere Elemente zuweisen.

Stacks

Das primäre Layoutelement #sidenav-container ist ein Raster, das eine Zeile und zwei Spalten erstellt. Eines davon hat den Namen stack. Wenn der Platz beschränkt ist, weist CSS alle Elemente des <main>-Elements untergeordnete Elemente denselben Rasternamen zu erhalten, wobei alle Elemente im selben Bereich platziert werden und ein Stapel erstellt wird.

#sidenav-container {
  display: grid;
  grid: [stack] 1fr / min-content [stack] 1fr;
  min-height: 100vh;
}

@media (max-width: 540px) {
  #sidenav-container > * {
    grid-area: stack;
  }
}

<aside> ist das Animationselement, das die seitliche Navigationsleiste enthält. Sie enthält Zwei untergeordnete Elemente: der Navigationscontainer <nav> namens [nav] und ein Hintergrund-<a> mit dem Namen [escape], mit dem das Menü geschlossen wird.

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

2fr anpassen und 1fr, um das gewünschte Verhältnis für das Menü-Overlay und die Schließen-Schaltfläche mit Negativraum zu finden.

<ph type="x-smartling-placeholder">
</ph> <ph type="x-smartling-placeholder"> <ph type="x-smartling-placeholder">
</ph> Eine Demo dazu, was passiert, wenn Sie das Seitenverhältnis ändern

CSS-3D-Transformationen und Übergänge

Unser Layout ist jetzt für die Größe eines mobilen Darstellungsbereichs gestapelt. Bis ich neue Stile hinzugefügt habe, wird standardmäßig der Artikel eingeblendet. Hier sind einige UX-Designs, auf die ich im nächsten Abschnitt stehe:

  • Öffnen und Schließen animieren
  • Nur mit Bewegung animieren, wenn der Nutzer damit einverstanden ist
  • Animieren Sie „visibility“, damit der Tastaturfokus nicht in das nicht sichtbare Element eindringt

Wenn ich mit der Implementierung von Bewegungsanimationen beginne, steht die Barrierefreiheit an erster Stelle.

Barrierefreie Bewegungen

Nicht jeder wünscht sich eine rutschende Bewegung. In unserer Lösung wird diese Einstellung wird angewendet, indem die CSS-Variable --duration in einer Medienabfrage angepasst wird. Dieser Medienabfragewert steht für die Betriebssystemeinstellung des Nutzers für Bewegung (falls verfügbar).

#sidenav-open {
  --duration: .6s;
}

@media (prefers-reduced-motion: reduce) {
  #sidenav-open {
    --duration: 1ms;
  }
}
<ph type="x-smartling-placeholder">
</ph> <ph type="x-smartling-placeholder">
Demo der Interaktion mit und ohne Anwendung der Dauer

Wenn die seitliche Navigationsleiste auf- und geschlossen wird, Ich verschiebe das Element sofort in den sichtbaren Zustand und behalte den Zustand ohne Bewegung bei.

Übergang, Transformieren, Übersetzen

Seitliche Navigationsleiste (Standard)

So setzen Sie den Standardstatus unserer Sidenav-Navigation auf dem Mobilgerät auf einen Nicht-Bildschirm. Ich platziere das Element mit transform: translateX(-110vw).

Hinweis: Ich habe dem üblichen Out-Screen-Code von -100vw eine weitere 10vw hinzugefügt. damit die box-shadow der seitlichen Navigationsleiste nicht in den Hauptdarstellungsbereich eindringt, wenn dieser ausgeblendet ist.

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

Wenn das #sidenav-Element mit :target übereinstimmt, setze die translateX()-Position auf die Basisstation 0. Sehen Sie sich an, wie CSS das Element von seiner Außenposition von -110vw nach „in“ verschiebt. Position von 0 über var(--duration), wenn der URL-Hash geändert wird.

@media (max-width: 540px) {
  #sidenav-open:target {
    visibility: visible;
    transform: translateX(0);
    transition:
      transform var(--duration) var(--easeOutExpo);
  }
}

Sichtbarkeit der Umstellung

Das Ziel ist nun, das Menü für Screenreader auszublenden, damit die Systeme nicht den Fokus auf ein Menü außerhalb des Bildschirms legen. Dazu lege ich eine Übergang zur Sichtbarkeit, wenn sich :target ändert.

  • Wenn Sie hineingehen, ändern Sie die Sichtbarkeit nicht. sofort sichtbar, damit ich sehen kann, dass sich das Element einschiebt und den Fokus akzeptiere.
  • Beim Ausgehen wird der Übergang mit der Sichtbarkeit verzögert, sodass er am Ende des Übergangs zu hidden wechselt.

UX-Verbesserungen der Barrierefreiheit

Diese Lösung stützt sich auf das Ändern der URL, damit der Status verwaltet wird. Natürlich sollte hier das <a>-Element verwendet werden, das auch sehr leicht zugänglich ist. Funktionen kostenlos zur Verfügung. Wir zeichnen unsere interaktiven Elemente mit Beschriftungen aus, die die Absicht klar artikulieren.

<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>
<ph type="x-smartling-placeholder">
</ph> <ph type="x-smartling-placeholder">
Eine Demo der User Experience für Voiceover und Tastaturinteraktion.

Jetzt geben unsere primären Interaktionsschaltflächen sowohl für die Maus als auch für die Tastatur klar ihre Absicht an.

:is(:hover, :focus)

Mit diesem praktischen CSS-Funktions-Pseudoselektor können wir schnell inklusiver werden. indem Sie sie mit Fokus teilen.

.hamburger:is(:hover, :focus) svg > line {
  stroke: hsl(var(--brandHSL));
}

JavaScript verwenden

Zum Schließen escape drücken

Mit der Taste „Escape“ auf deiner Tastatur sollte das Menü geschlossen werden. Ist das richtig? Verkabeln wir das jetzt.

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

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

Um zu verhindern, dass beim Öffnen und Schließen mehrere in den Browserverlauf aufnehmen, fügen Sie folgenden JavaScript-Code Schaltfläche „Schließen“:

<a href="#" id="sidenav-close" title="Close Menu" aria-label="Close Menu" onchange="history.go(-1)"></a>

Dadurch wird der URL-Verlaufseintrag beim Schließen entfernt, sodass es so aussieht, als wäre das Menü noch nie geöffnet wurde.

Fokus auf UX legen

Das nächste Snippet hilft uns, den Fokus auf die Schaltflächen zum Öffnen und Schließen nach der öffnen oder schließen. Ich möchte das Wechseln einfach machen.

sidenav.addEventListener('transitionend', e => {
  const isOpen = document.location.hash === '#sidenav-open';

  isOpen
      ? document.querySelector('#sidenav-close').focus()
      : document.querySelector('#sidenav-button').focus();
})

Wenn die seitliche Navigationsleiste geöffnet wird, fokussieren Sie die Schaltfläche zum Schließen. Wenn die seitliche Navigationsleiste geschlossen wird, um den Fokus auf die Schaltfläche „Öffnen“ zu legen. Dazu rufe ich in JavaScript focus() für das Element auf.

Fazit

Jetzt, da du weißt, wie ich das gemacht habe, wie würdest du es tun?! Dadurch entsteht eine unterhaltsame Komponentenarchitektur! Wer erstellt die erste Version mit Slots? 🙂

Gestalten Sie die und lernen alle Möglichkeiten kennen, das Web zu nutzen. Störung erstellen, Tweets über Ihre Version und ich füge sie Community-Remixe weiter unten.

Community-Remixe