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">Webtaktik
In dieser explorativen Datenanalyse habe ich einige wichtige Webplattformfunktionen kombiniert:
- Preisvergleichsportal
:target
- CSS-Raster
- CSS-Transformationen
- CSS-Medienabfragen für Darstellungsbereich und Nutzereinstellungen
- 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;
}
}
Menühintergrund
<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.
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;
}
}
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
Links
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>
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
- @_developit mit benutzerdefinierten Elementen: demo & Code
- @mayeedwin1 mit HTML/CSS/JS: Demo und Code
- @a_nurella mit Glitch-Remix: Demo und Code
- @EvroMalarkey mit HTML/CSS/JS: Demo und Code