Responsive, Pure CSS Off-Canvas Hamburger Menu

, Author

Ultimo aggiornamento del 21 gennaio 2019.

I puri CSS off-canvas hamburger menu non sono una scoperta recente. Dopo tutto, Chris Coyier ha scritto su questa tecnica nel novembre del 2012.

  • Se questo è un vecchio trucco per te, allora resta con me per un po’. Ho migliorato l’esempio di Chris e mi piacerebbe avere il tuo feedback.
  • Se questo è nuovo per te, non preoccuparti. Avete molta compagnia, dato che sembra che gran parte del web non abbia ancora preso piede.

Con questo, costruiremo un semplice, reattivo menu hamburger off-canvas usando solo CSS che sarà facile da incorporare nel vostro progetto. Ma prima…

Cosa c’è di sbagliato in JavaScript?

Niente.

Aaron Gustafson spiega l’importanza dei Progressive Enhancements e il ruolo di JavaScript nello sviluppo web meglio di quanto potrei mai fare io. Dovreste leggere il suo post. Ma per amore della brevità, cercherò di riassumerlo:

  • “I compiti fondamentali possono sempre essere svolti senza JavaScript.”
  • I compiti fondamentali dovrebbero essere svolti sul livello più stabile (cioè non JavaScript).
  • Progressive Enhancements non è anti-JavaScript. Si tratta solo di abbracciare le tecnologie giuste sul livello giusto.
  • “Poiché c’è qualche possibilità che JavaScript non funzioni, dobbiamo sempre tenere conto di questa possibilità”
  • Non è mai una buona idea ignorare i potenziali utenti.
  • I miglioramenti progressivi sono solo buona ingegneria.

Quindi, faremo il più possibile con HTML e CSS. Poi faremo fare a JavaScript la sua magia su uno strato più appropriato – migliorando l’UI già esistente.

Step 1: HTML

Come forse sapete, il primo passo è sempre scrivere un solido, ben pensato, strato base di HTML.

Nota: sto usando Font Awesome per le icone nel mio esempio.

Passo 1: HTML iniziale per un puro CSS responsive hamburger menu

Sembra piuttosto standard, vero? Abbiamo:

  • Il nostro elemento padre <header>
  • L’icona hamburger (“fa-bars”)
  • Un’intestazione principale (o potenzialmente un logo)
  • La navigazione in un elemento <nav>
  • Un’icona di chiusura (“fa-close”) all’interno della navigazione (più avanti)
  • Un “fondale” dopo la navigazione. Perché è un tag di ancoraggio? Lo spiegherò più tardi.

Passo 2: rendiamolo più accessibile

L’accessibilità non dovrebbe mai essere un pensiero dopo – come dopo aver scritto l’applicazione. Dovrebbe essere pianificata dall’inizio. Aggiungere alcune considerazioni di base ora non solo migliorerà l’accessibilità generale del tuo sito, ma fornirà a te (lo sviluppatore) un migliore markup da utilizzare nel tuo JavaScript!

Con questo, aggiungeremo qualche altro attributo e del testo per soli lettori di schermo:

Step 2: Migliorare l’HTML per essere più accessibile.

Ecco una rapida ripartizione di tutti questi attributi e come funzionano:

  • Abbiamo aggiunto degli ID unici per indirizzare le nostre HREF (più avanti su come funziona).
  • Abbiamo fornito un’etichetta informativa dei pulsanti per gli screen reader usando .
  • Abbiamo nascosto le icone agli screen reader con , perché sono rappresentazioni visive, e aggiunto del testo per soli screen-reader con gli elementi <span class=”sr-only”>.
  • Abbiamo tolto lo “sfondo” dall’indice di tabulazione con un . È di natura puramente visiva e non vogliamo confondere i nostri utenti ipovedenti e con la tastiera.
  • Abbiamo aggiunto l’attributo amazing per impostare lo stato iniziale (e semantico) dello “sfondo”. Niente più spazzatura – che emozione!

Ecco il risultato finora:

Figura 1: Risultato della visualizzazione dell’HTML dopo i passi 1 e 2.

Passo 3: Diamo stile!

Avremo un approccio mobile-first, quindi eliminiamo la vista mobile, “hamburger-y” (la parte interessante).

Prima di tutto, ci limiteremo a ottenere il giusto layout dell’intestazione (senza l’interattività):

Step 3: Aggiungere alcuni CSS per dare stile all’intestazione (senza interattività, per ora).

Il risultato:

Figura 2: Visualizzazione risultante del CSS HTML & dopo il passo 3.

Passo 4: Interattività con puro CSS

Quando si rendono interattivi i widget con i CSS, si hanno un paio di opzioni:

  1. Utilizzare radio o checkbox
  2. Utilizzare la pseudo classe :target.

Radio e checkbox funzionano incredibilmente bene per molti widget, come tabs, modals, dropdowns e accordions. Chris Coyier ha soprannominato questa tecnica “the checkbox hack”. Diversi sviluppatori hanno usato questo “hack” per i loro menu off-canvas, come nel tutorial di Paul Lewis per Chrome Dev Summit o il menu hamburger morphing di Luis Manuel.

Tuttavia, la pseudo-classe :target è più semantica in questo caso d’uso, poiché abbiamo a che fare direttamente con la navigazione. Potresti non essere d’accordo, e questo è completamente ok! Sarebbe incredibilmente facile e perfettamente accettabile scambiare la pseudo-classe :target per una checkbox.

Entrambe le tecniche hanno i loro limiti, però.

Utilizzando una checkbox:

  • Richiede a JavaScript di chiudere il menu off-canvas se uno dei link all’interno del menu era un anchor link ad una sezione specifica della stessa pagina.
  • Richiede che il campo <input> sia un fratello del menu o almeno un fratello dell’antenato del menu. In altre parole, il CSS è un po’ più complicato. Puoi avere la <label> (anche etichette multiple) altrove, comunque.
  • L’elemento <label> non sarà direttamente focalizzabile o tabulabile, richiedendo un CSS leggermente più complicato per gestire il focus sulla checkbox mentre si cambia l’aspetto visibile della <label>.
  • La navigazione da tastiera intorno all’apertura/chiusura del menu sarà strana. Il cambiamento di stato di una casella di controllo è fatto attraverso il tasto, non il tasto. Mentre gli utenti non vedenti possono capire che il widget è azionato da una casella di controllo, gli utenti vedenti con la tastiera saranno confusi poiché la casella di controllo non è evidente – qualcosa che ho sentito essere un problema in questo caso d’uso.

Utilizzando la pseudo-classe :target:

  • aggiunge l’apertura/chiusura del menu off-canvas alla storia del browser (spingendo l’hash nella barra degli indirizzi). Richiederà a JavaScript di eseguire Event.preventDefault() per evitare questo (e il potenzialmente fastidioso salto all’inizio della pagina).

E potrebbero esserci altri avvertimenti che mi sono perso. In ogni caso, scegliere quale tecnica è una questione di preferenza e soggetta ai requisiti del vostro progetto. Comunque, ho divagato…

Ecco la parte interattiva del CSS:

Passo 4: Aggiungere del CSS per l’interattività.

Il risultato quando si clicca:

Figura 3: Risultato della visualizzazione del menu hamburger quando viene aperto.

Come funziona tutto questo

In sostanza, la pseudo-classe :target ci dà un nuovo “stato” per lo stile della navigazione mirata. Quando main-menu è stato mirato (con il suo hash aggiunto all’URL) possiamo ora far scorrere fuori il menu. È un po’ come una pseudo-classe :focus per l’elemento mirato (non il link stesso).

Abbiamo anche permesso allo “sfondo” di essere visualizzato quando la navigazione è mirata.

Si noterà che l’icona hamburger principale è collegata all’ID della navigazione, mentre sia l’icona di chiusura che i pulsanti dello sfondo sono collegati all’icona hamburger principale. Questo ci permette di cliccare sull’icona di chiusura o sullo sfondo per rimuovere il “focus” – o meglio :target – dalla navigazione. Se lo sfondo non fosse un link, non sarebbe cliccabile senza JavaScript.

Ho anche concatenato i selettori :target con l’attributo nel CSS. Questo sarà alla fine il punto in cui miglioreremo progressivamente il menu hamburger con JavaScript per non saltare all’intestazione quando viene cliccato – evitando l’avvertimento che ho menzionato prima. Avere il JavaScript che dirotta il comportamento dell’hash del browser significa che la pseudo-classe :target non funzionerà più. Quando questo accadrà, approfitteremo dell’attributo per stilizzare il toggling con valori vero/falso come avremmo potuto fare in passato con le classi.

Nel frattempo, però, questo funziona splendidamente senza JavaScript.

Ho aggiunto la media query @supports per fornire il CSS preferito position:fixed ai browser (sia mobile che desktop) che lo supportano. Altrimenti, i browser e i dispositivi sfigati – sto guardando te iOS – avranno position:absolute.

Passo 5: Stili per schermi più grandi

Siccome non vogliamo che il menu hamburger venga visualizzato per dispositivi non mobili (o schermi più grandi in generale), aggiungeremo la media query necessaria per questo. Poi gli daremo lo stile di una navigazione orizzontale:

Passo 5: CSS per lo stile della navigazione su schermi più grandi.

Il risultato:

Figura 4: Visualizzazione risultante della navigazione stilizzata per schermi più grandi.

Voila! Abbiamo finito!

Mettendo tutto insieme

Ecco l’HTML finale:

L’HTML finale per il menu hamburger reattivo usando solo CSS.

Ecco il CSS finale:

Finale CSS per il responsive hamburger menu.

Demo

Prova tu stesso il mio CodePen:
→ Pure CSS Hamburger Menu senza JavaScript.

Nota: puoi provare anche la versione con checkbox del menu.

Vuoi aggiungere JavaScript per renderlo più brillante?

Mentre possiamo far funzionare il menu off-canvas interamente con i CSS – migliorandone le prestazioni e l’affidabilità – avremo comunque bisogno che JavaScript ci assista in qualche modo per migliorare l’interattività che circonda i difetti di entrambe le tecniche. È anche possibile utilizzare JavaScript per impedire lo scorrimento della pagina mentre il menu è aperto.

E’ anche da notare che un livello decente (e probabilmente il più importante) di accessibilità può essere raggiunto senza JavaScript. Tuttavia, è difficile fornire un robusto livello di accessibilità senza la capacità di JavaScript di manipolare il DOM (ad esempio la gestione del focus, gli aggiornamenti degli attributi ARIA, ecc.)

Per maggiori informazioni su come migliorare l’accessibilità del tuo sito web attraverso JavaScript, controlla i seguenti articoli:

  • Usare gli attributi ARIA per l’impostazione dello stato di JavaScript& styling
  • Scrivere JavaScript con l’accessibilità in mente

Hai altri pensieri o suggerimenti?

Mi piacerebbe sentire i tuoi commenti sul mio approccio a un puro menu hamburger CSS.

Modifiche e ruminazioni successive

21 gennaio 2019: articolo modificato e esempi di codice aggiornati per rimuovere gli attributi ARIA non necessari e migliorare l’accessibilità.

Come ho imparato di più sull’uso di ARIA e sullo sviluppo di & test per l’accessibilità in generale, mi sono reso conto di alcune cose:

  1. JavaScript ha sicuramente il suo posto, e dovrebbe essere parte di qualsiasi modello di accessibilità UI robusto.
  2. A eccezione dei punti di riferimento ARIA, JavaScript è necessario per usare ARIA correttamente. E, molti degli attributi che ho usato, come sono meglio lasciati per JavaScript da aggiungere una volta caricati invece di aggiungerli direttamente nel markup. Questo concetto segue le buone pratiche di Progressive Enhancement – gli stati e le proprietà di ARIA insieme a JavaScript sono un aggiornamento e dovrebbero essere gestiti su un livello separato.
  3. In precedenza, non ho gestito correttamente il focus, in quanto il focus scompariva man mano che procedeva attraverso i link visivamente nascosti (quando collassati). Ho aggiunto un display: none; al CSS del menu per risolvere questo problema.

Quindi, se hai implementato una versione precedente del mio Pure CSS Off-Canvas Hamburger Menu, considera l’aggiornamento a questa versione più semplice e accessibile!

Lascia un commento

Il tuo indirizzo email non sarà pubblicato.