Costruire un menu mobile progressivamente migliorato che funziona senza JavaScript
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.
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:
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:
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à):
Il risultato:
Passo 4: Interattività con puro CSS
Quando si rendono interattivi i widget con i CSS, si hanno un paio di opzioni:
- Utilizzare radio o checkbox
- 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:
Il risultato quando si clicca:
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:
- JavaScript ha sicuramente il suo posto, e dovrebbe essere parte di qualsiasi modello di accessibilità UI robusto.
- 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.
- 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!