Una panoramica di base su come creare una navigazione laterale reattiva con slide
In questo post voglio condividere con voi come ho prototipato un componente di navigazione laterale per il web che è reattivo, stateful, supporta la navigazione da tastiera, funziona con e senza JavaScript, e funziona su tutti i browser. Prova la demo.
Se preferisci i video, ecco una versione di questo post su YouTube:
Panoramica
È difficile creare un sistema di navigazione reattivo. Alcuni utenti usano una tastiera, altre dispongono di desktop potenti e altre ancora da un piccolo dispositivo mobile. Chiunque visiti il tuo sito dovrebbe essere in grado di aprire e chiudere il menu.
Tattiche sul web
In questa esplorazione dei componenti ho avuto la gioia di combinare alcune funzionalità fondamentali della piattaforma web:
- Servizio di shopping comparativo
:target
- Griglia CSS
- CSS trasforma
- Query multimediali CSS per area visibile e preferenza dell'utente
- JS per
focus
miglioramenti dell'esperienza utente
La mia soluzione ha una barra laterale e attiva/disattiva solo quando si trova su un dispositivo mobile area visibile di 540px
o inferiore.
540px
sarà il nostro punto di interruzione per passare dal layout interattivo mobile a quello statico per computer e viceversa.
Pseudo-classe :target
CSS
Un link <a>
imposta l'hash dell'URL su #sidenav-open
e l'altro su vuoto (''
).
Infine, un elemento ha id
per corrispondere all'hash:
<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>
Facendo clic su ciascuno di questi link viene modificato lo stato hash dell'URL della nostra pagina. quindi con una pseudo-classe mostro e nascono la barra laterale:
@media (max-width: 540px) {
#sidenav-open {
visibility: hidden;
}
#sidenav-open:target {
visibility: visible;
}
}
Griglia CSS
In passato, utilizzavo solo la posizione assoluta o fissa
layout e componenti della navigazione laterale. La griglia però, con la sua sintassi grid-area
,
consente di assegnare più elementi
alla stessa riga o colonna.
Impilati
L'elemento di layout principale #sidenav-container
è una griglia che crea una riga e due colonne,
1 di ognuno ha il nome stack
. Quando lo spazio è vincolato, il CSS assegna tutti gli elementi dell'elemento <main>
secondari con lo stesso nome della griglia, posizionando tutti gli elementi nello stesso spazio, creando una pila.
#sidenav-container {
display: grid;
grid: [stack] 1fr / min-content [stack] 1fr;
min-height: 100vh;
}
@media (max-width: 540px) {
#sidenav-container > * {
grid-area: stack;
}
}
Sfondo del menu
<aside>
è l'elemento animato che contiene la barra di navigazione laterale. Ha
2 elementi secondari: il contenitore di navigazione <nav>
denominato [nav]
e uno sfondo <a>
denominato [escape]
, che viene utilizzato per chiudere il menu.
#sidenav-open {
display: grid;
grid-template-columns: [nav] 2fr [escape] 1fr;
}
Modifica 2fr
e 1fr
per trovare le proporzioni che preferisci per l'overlay del menu e il relativo pulsante di chiusura dello spazio negativo.
Trasformazioni 3D CSS e transizioni
Il nostro layout è ora impilato con dimensioni dell'area visibile su dispositivi mobili. Finché non aggiungo nuovi stili, si sovrappone al nostro articolo per impostazione predefinita. Ecco alcune UX che cercherò nella prossima sezione:
- Anima apertura e chiusura
- L'animazione con il movimento viene eseguita solo se l'utente è d'accordo.
- Attiva l'animazione
visibility
in modo che lo stato attivo della tastiera non entri nell'elemento fuori schermo
Man mano che inizio a implementare le animazioni di movimento, voglio partire con la massima priorità sull'accessibilità.
Movimenti accessibili
Non a tutti vorranno provare l'esperienza di movimento. Nella nostra soluzione, questa preferenza
viene applicata regolando una variabile CSS --duration
all'interno di una query multimediale. Questo valore di query supporti rappresenta
alle preferenze del sistema operativo di un utente per il movimento (se disponibile).
#sidenav-open {
--duration: .6s;
}
@media (prefers-reduced-motion: reduce) {
#sidenav-open {
--duration: 1ms;
}
}
Ora, quando la barra di navigazione laterale scorre aperta e chiusa, se un utente preferisce movimento ridotto, Sposto immediatamente l'elemento in vista, mantenendo lo stato senza movimento.
Transizione, trasformazione e traslazione
Navigazione laterale in uscita (predefinita)
Per impostare lo stato predefinito della nostra navigazione laterale sui dispositivi mobili su uno stato fuori schermo:
posiziono l'elemento con transform: translateX(-110vw)
.
Tieni presente che ho aggiunto un altro 10vw
al codice tipico fuori schermo di -100vw
,
per assicurarti che box-shadow
della barra di navigazione laterale non sblocchi nell'area visibile principale quando è nascosta.
@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);
}
}
Navigazione laterale in
Quando l'elemento #sidenav
corrisponde a :target
, imposta la posizione translateX()
su base 0
,
e osserva come CSS fa scorrere l'elemento dalla posizione di uscita -110vw
alla posizione "in"
posizione di 0
su var(--duration)
quando l'hash dell'URL viene modificato.
@media (max-width: 540px) {
#sidenav-open:target {
visibility: visible;
transform: translateX(0);
transition:
transform var(--duration) var(--easeOutExpo);
}
}
Visibilità delle transizioni
Ora l'obiettivo è nascondere il menu
agli screen reader quando è disattivato.
in modo che i sistemi non mettano lo stato in evidenza su un menu fuori schermo. A tal fine, imposto un
transizione alla visibilità quando cambia il valore :target
.
- Quando entri, non cambiare la visibilità; saranno visibili subito, così posso vedere l'elemento scorrere e accettare lo stato attivo.
- Quando esci, la visibilità delle transizioni è ritardata, quindi al termine dell'uscita il passaggio passa a
hidden
.
Miglioramenti dell'esperienza utente per l'accessibilità
Link
Questa soluzione si basa sulla modifica dell'URL per la gestione dello stato.
Ovviamente, l'elemento <a>
dovrebbe essere usato qui e ha una buona accessibilità
funzioni senza costi. Adoriamo i nostri elementi interattivi con etichette che indicano chiaramente le intenzioni degli utenti.
<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>
Ora i nostri pulsanti di interazione principali indicano chiaramente il loro intento sia per il mouse che per la tastiera.
:is(:hover, :focus)
Questo pratico pseudo-selettore funzionale CSS ci consente di essere rapidamente inclusivi con i nostri stili al passaggio del mouse condividendoli con lo stato attivo.
.hamburger:is(:hover, :focus) svg > line {
stroke: hsl(var(--brandHSL));
}
Aggiungi elementi su JavaScript
Premi escape
per chiudere
Il tasto Escape
sulla tastiera dovrebbe chiudere il menu. Colleghiamolo.
const sidenav = document.querySelector('#sidenav-open');
sidenav.addEventListener('keyup', event => {
if (event.code === 'Escape') document.location.hash = '';
});
Cronologia del browser
Per evitare che le interazioni di apertura e chiusura si sovrappongano più voci nella cronologia del browser, aggiungi il seguente codice JavaScript in linea pulsante di chiusura:
<a href="#" id="sidenav-close" title="Close Menu" aria-label="Close Menu" onchange="history.go(-1)"></a>
La voce della cronologia degli URL verrà rimossa alla chiusura, creando così come se il menu fosse mai aperto.
Concentrati sull'esperienza utente
Lo snippet successivo ci aiuta a mettere in risalto i pulsanti di apertura e chiusura dopo si aprono o si chiudono. Voglio semplificare l'attivazione/disattivazione.
sidenav.addEventListener('transitionend', e => {
const isOpen = document.location.hash === '#sidenav-open';
isOpen
? document.querySelector('#sidenav-close').focus()
: document.querySelector('#sidenav-button').focus();
})
Quando si apre la barra di navigazione laterale, imposta lo stato attivo sul pulsante di chiusura. Quando la barra di navigazione laterale si chiude,
imposta lo stato attivo sul pulsante di apertura. Per farlo, richiamo focus()
sull'elemento in JavaScript.
Conclusione
Ora che sai come ci ho fatto, come lo faresti?! Ciò rende l'architettura dei componenti divertente. Chi produrrà la prima versione con gli slot? 🙂
Diversifica il nostro e scoprire tutti i modi per creare sul web. Crea un Glitch. invia un tweet alla tua versione e la aggiungerò al Sezione Remix della community di seguito.
Remix della community
- @_developit con elementi personalizzati: demo & codice
- @mayeedwin1 con HTML/CSS/JS: demo & codice
- @a_nurella con un remix Glitch: demo e codice
- @EvroMalarkey con HTML/CSS/JS: demo & codice