Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

Menu mega dropdown con CSS e jQuery

Realizziamo insieme un esempio di menu a discesa oggi molto in voga
Realizziamo insieme un esempio di menu a discesa oggi molto in voga
Link copiato negli appunti

Dopo il Menu dropdown in stile Facebook torniamo a parlare di menu, e in particolare di una tipologia piuttosto recente e in costante diffusione: i mega-dropdown. Ecco le caratteristiche salienti di un mega-dropdown secondo Jakob Nielsen:

  • Grandi pannelli bidimensionali divisi in gruppi di opzioni di navigazione
  • Scelte di navigazione strutturate attraverso il layout, la tipografia e a volte icone
  • Tutto visibile da subito, senza la necessità di scrolling

Nielsen sostiene in Mega Drop-Down Navigation Menus Work Well che i mega-dropdown superano gli svantaggi dei menu dropdown tradizionali
e ne raccomanda l'impiego nel web design.

In questo articolo vedremo una possibile implementazione di mega-dropdown con HTML, CSS e Javascript per arrivare ad ottenere una solida base flessibile e facilmente personalizzabile. Vediamo subito l'esempio
e il suo screenshot:

Figura 1 - Screenshot dell'esempio
esempio

Ho voluto realizzare un menu che sia il più possibile vicino ad un esempio reale di utilizzo (nel caso specifico un sito e-commerce di elettronica) così da mostrare come sia molto più fruibile, compatto e navigabile un mega-dropdown rispetto ad un dropdown tradizionale.

Per implementare una navigazione simile con l'approccio classico sarebbero state necessarie molte
più voci di primo livello e/ probabilmente un menu a due sottolivelli.

Sarà chiaro al lettore che i mega-drop down consentono una maggiore strutturabilità
della navigazione e risultano particolarmente indicati per menu a molte voci e/o sezioni,
ad esempio in siti quali e-commerce, portali e siti Web 2.0. Come per i menu dropdown, sono però necessarie alcune premesse:

  • A beneficio degli utenti che navigano con screenreader, dispositivi mobili o browser obsoleti, le voci di primo livello dovranno essere link verso pagine che contengono una navigazione supplementare, e diversa dal menu stesso attraverso la quale è possibile rangiungere ogni sottosezione e pagina.
  • Per tutti gli altri utenti è necessario poter fornire la miglior navigabilità possibile
    e quindi garantire la massima compatibilità cross-browser e un'interazione efficace anche in assenza di Javascript. Quest'ultimo può essere impiegato però per arricchire l'esperienza di navigazione e migliorare l'usabilità del menu.
  • I menu megadropdown consentono molta flessibilità nella loro struttura: è importante però che le voci principali e le varie sottosezioni del menu siano correlate e facilmente identificabili.

Detto ciò siamo pronti a procedere con il processo di realizzazione del nostro esempio che attraversa essenzialmente tre fasi: HTML, CSS e Javascript.

Il markup del menu

Una buona interfaccia utente parte soprattutto da una scelta di markup che sia il più semantica
possibile e consenta una presentazione adeguata e comprensibile anche in assenza di CSS. In tal
senso, è noto a tutti che qualsiasi menu andrebbe strutturato attraverso una lista, e anche il nostro
megadropdown non fa eccezione, seppur con una maggiore complessità. Le voci principali e i titoli delle sottosezioni devono in questo caso rispettare una gerarchia tipografia svincolata dai fogli di stile.

Trattandosi per lo più di titoli, la scelta ricade quindi su h2 e h3. Con i titoli h2 racchiuderemo le voci principali del menu, mentre con gli h3 le sottosezioni.

All'interno delle voci <li> principali vi saranno dei div con classe "mega" che contengono i titoli e le sottosezioni. Insieme alla questa classe è possibile attribuire altre classi ai pannelli principali, così da formattarli su una, due, tre o quattro colonne (implementate attraverso div) o allinearli a destra o sinistra. L'utilizzo delle classi multiple nel markup ci permette quindi molta flessibilità di realizzazione. Vediamo a questo punto un estratto del markup dell'esempio:

<ul id="nav">
<li>
   <h2><a href="#">Home</a></h2>
</li>
<li>
   <h2><a href="#">Sezione a due colonne - default</a></h2>
   <div class="mega">
      <div>
            <h3><a href="#">Titolo 1a sezione</a></h3>
            <ul>
                <li><a href="#">...</a></li>
            </ul>
      </div>
      <div>
            <h3><a href="#">Titolo 2a sezione</a></h3>
            <ul>
                <li><a href="#">...</a></li>
            </ul>
      </div>
   <div>
</li>
<li>
   <h2><a href="#">Voce per sezione a tre colonne</a></h2>
   <div class="mega wide">
      <div>
        <!-- prima sezione -->
      </div>
      <div>
        <!-- seconda sezione -->
      </div>
      <div>
        <!-- terza sezione -->
      </div>
   </div>
</li>
</ul>

Per ogni pannello, indicato dalla classe "mega", dovranno essere inseriti i div
per contenere le sezioni verticali: queste ultime potranno contenere qualsiasi elemento tranne i div, ma titoli h3 e liste sono del tutto opzionali. Di default la classe "mega" conterrà un pannello a due sezioni affiancate, per ottenere un pannello a tre e quattro sezioni le classi multiple da usare sono rispettivamente "mega wide" e "mega ultra". Se invece avremo la necessità di avere una sola sezione (come nel caso della voce "Fotografia" dell'esempio) basterà attribuire le classi "mega small".

E' stata prevista nel markup anche una classe "alt" da aggiungere ai div-pannelli
per consentire l'allineamento sulla destra delle voci del menu mediante i CSS, come nel caso dell'ultima
voce dell'esempio.

Ecco quindi come rende il nostro menu senza CSS e senza Javascript:
si può notare la gerarchia visiva delle voci e la struttura che ricalca la suddivisione logica delle varie voci e sottovoci del menu. Questo è tutto per quanto riguarda il markup e le possibilità offerte dalle classi per i sottomenu, siamo ora pronti a procedere con il CSS del nostro esempio.

Il CSS del mega-dropdown

Il CSS del nostro esempio è piuttosto corposo, ma è composto da semplici dichiarazioni ed è libero da hack. E' bene iniziare con lo sviluppare un menu che sia totalmente funzionale nei browser moderni senza la necessità di Javascript: in tal senso il meccanismo alla base dell'effetto a comparsa è cruciale. Come nel caso del menu dropdown semplice, si tratta in questo di nascondere (o meglio, traslare fuori dalla finestra) le sottovoci in stato normale, per poi riposizionarle in stato :hover dei list-item che li contengono.

Volendo ridurre al minimo il CSS dell'esempio senza Javascript,
le regole con le dichiariazioni essenziali sono le seguenti:

ul#nav{height: 26px}
ul#nav li{float: left;position: relative}
ul#nav li li{float: none} /*annulla i float su eventuali li annidati*/
ul#nav div.mega{position: absolute;top: -9999px;left: -1px;width: 20em;
    overflow:hidden; /*per contenere i float*/}
ul#nav div.mega.alt{left:auto;right:-1px} /*per i sottomenu allineati sul lato destro*/
ul#nav li:hover div.mega{top: 25px}
ul#nav div.mega div{float: left;width: 49%}

La barra di navigazione viene dichiarata alta 26 pixel e i list-item di primo livello vengono affiancati rendendoli float e posizionati relativamente così da creare un contesto di posizionamento per i pannelli a comparsa. Questi ultimi vengono dichiarati larghi 20em e posizionati a -1px dal lato sinistro del list-item che li contiene e traslati di 9999 pixel verso l'alto in stato normale: saranno quindi portati fuori dalla finestra, ma comunque accessibili a screen reader grazie a una variante della tecnica off-left.
Vengono dichiarati inoltre overflow:hidden così da contenere i float al loro interno.

I sottomenu con classe "mega alt" vengono invece allineati sul lato destro, impostando
la proprietà left su auto e definendo la proprietà right. In fase hover dei list-item
principali, i sottomenu vengono quindi mostrati sotto il menu agendo sulla proprietà top:
questa regola ha quindi l'effetto voluto sia sui pannelli allineati a sinistra che quelli allineati a destra. Per i pannelli con classe mega, che di default contiene due sezioni affiancate, i div innestati saranno larghi ciascuno il 49% del loro contenitore.

Con queste fondamentali indicazioni in termini di accessibilità generale termina la prima parte. Vedremo nella seconda come perfezionare il menu nei suoi aspetti di presentazione e interazione con l'utente tramite Javascript.

Questo a grandi linee il CSS del nostro esempio, che si suddivide in realtà in quattro
blocchi principali:

  • Regole generiche e specifiche per le voci principali del menu
  • Regole per il meccanismo a comparsa dei sottomenu
  • Regole per le varie tipologie di pannello
  • Regole aggiuntive

Il CSS risultante è di circa 30 regole, vediamolo a questo punto per intero:

/* tipografia, colori e regole per voci di primo livello, titoli e link */

div#menu{padding-top:100px;width:100%;
    background: #444 url(menubk.png) repeat-x bottom}
ul#nav,ul#nav li,ul#nav ul{margin:0;padding:0;list-style:none}

ul#nav{width:850px;margin: 0 auto;height:26px;
    background: #5898F2 url(menubk.png) repeat-x;
    font: 70%/1.5 Verdena,Tahoma,sans-serif}
ul#nav a{display:block;text-decoration:none}
ul#nav h2{font-size:110%;margin:0}
ul#nav h2 a{line-height:25px;padding: 0 15px;color:#FFF}
ul#nav>li:hover,ul#nav h2 a:hover{background: #5092F2}
ul#nav h3{font-size:100%;margin:0}
ul#nav h3 a{color: #666}
ul#nav h3 a:hover{text-decoration:underline}
ul#nav li{float: left;position: relative}
ul#nav li li{float: none;display: block !important;display: inline; /*IE6*/}

/*dichiarazioni chiave per i sottomenu e l'effetto a comparsa
NB: classe open è necessaria per JQuery*
/

ul#nav div.mega{position: absolute;top: -9999px;left: -1px;
    width: 20em;padding: 0.7em;border: 1px solid #5898F2;
    background: #FFF;overflow:hidden;line-height:1.5}
ul#nav li:hover div.mega,ul#nav li div.mega.open{top: 25px;z-index: 100}

/*tipologie di sottomenu:
small: colonna singola
mega: 2 colonne - default
wide: 3 colonne
ultra: 4 colonne
alt: allineato sul lato destro */

ul#nav div.mega div{float:left;width:49%}
ul#nav div.mega.small{width:12em}
ul#nav div.mega.small div{float:left;width:99.9%}
ul#nav div.mega.wide{width:28em}
ul#nav div.mega.wide div{float:left;width:33%}
ul#nav div.mega.ultra{width:36em}
ul#nav div.mega.ultra div{float:left;width:24.9%}
ul#nav div.mega.alt{left:auto;right:-1px}

/*regole aggiuntive per i link dei sottomenu*/

ul#nav div.mega li a{padding:0 7px;color: #267BEE;
    background: #FFF url(bullet.png) no-repeat left center;}
ul#nav div.mega li a:hover{color: #0B4295;text-decoration:underline}

Pur essendo corposo, il CSS è per lo più composto da dichiarazioni semplici su
dimensioni, tipografia e colori. Nell'esempio completo con solo i CSS,
si noterà che appena il puntatore del mouse lascia una voce principale, il relativo sottomenu scompare immediatamente. Una buona regola, consigliata anche da J.Nielsen nell'articolo citato in apertura, è avere una chiusura ritardata per i sottomenu. Dopo aver quindi reso perfettamente funzionale un menu mega-dropdown con soli HTML e CSS, non ci resta che migliorarlo con Javascript. Vediamo come.

Il Javascript

Riprendiamo quindi al nostro esempio principale e vediamo brevemente la parte relativa allo scripting. C'è da premettere che il menu, come abbiamo visto nella sezione precedente, è totalmente funzionale sui browser moderni anche con Javascript disabilitato. L'impiego di Javascript ha però molteplici motivi, tra cui:

  • Estendere la compatibilità del menu anche su IE6
  • Migliorare l'usabilità del menu, mostrando i sottomenu aperti solo nel caso in cui è intenzione dell'utente
  • Migliorare l'interazione dell'utente ritardando la scomparsa dei sottomenu quando allontana il puntatore del mouse da una voce principale

Per quanto riguarda la scelta implementativa, ho optato come per il menu dropdown semplice all'accoppiata JQuery e hoverIntent. Il primo perchè è un framework compatto e potente, il secondo per il fatto che è in grado di gestire la fase :hover di qualsiasi elemento "cercando di capire" le intenzioni dell'utente: passaggi fortuiti sulle voci principali del menu non causeranno l'apertura dei sottomenu, così come abbandoni accidentali non ne causeranno la chiusura immediata.

JQuery e HoverIntent forniscono quindi una solida base e il risultato è uno script dedicato di
appena cinque righe che serve per mostrare i sottomenu con un bell'effetto a tendina, gestire i sottomenu in maniera attenta all'utente ed evitare che due sottomenu siano visualizzati nello stesso istante. C'è da notare infatti che nell'esempio quando si esce totalmente dal menu, il sottomenu scompare dopo circa mezzo secondo con un'effetto a tendina, mentre quando si passa da una voce all'altra la chiusura della prima è immediata per evitare sovrapposizioni.

In quanto allo script, la sua spiegazione esula dallo scopo dell'articolo e lascio il suo
studio all'appassionato di scripting, ma c'è un aspetto fondamentale che chiunque abbia intenzione di utilizzare il menu dovrebbe conoscere. In assenza di Javascript, la chiusura di un sottomenu menu è istantanea nel momento in cui si abbandona la sua voce principale. Per far di modo che la chiusura sia posticipata, javascript deve quindi ridefinire il comportamento del CSS, mantenendo aperto il sottomenu per poi nasconderlo dopo 500 millisecondi. Per l'aspetto relativo alla temporizzazione hoverIntent è perfetto, per la ridefinizione del CSS dovremo fare in modo che sia lo script ad hoc ad occuparsene.

Ho quindi pensato di replicare la fase :hover delle voci principali del menu attraverso una
classe "open" che non verrà mai usata nel CSS, ma verrà attribuita dal Javascript ai sottomenu per mantenerne l'apertura in fase di rollout. Basta in questo caso aggiungere il relativo selettore e replicare il blocco dichiarativo per la fase :hover delle voci principali. Ecco la regola CSS completa nel nostro esempio:

ul#nav li:hover div.mega,ul#nav li div.mega.open{top: 25px;z-index: 100}

Con questo piccolo accorgimento, lo script dedicato che si trova nel file jquery-mdd.js si occuperà quindi di gestire aperture e chiusure dei sottomenu come nel caso dell'esempio. Questa è in effetti l'unica accortezza aggiuntiva per poter abilitare Javascript, che di norma non richiederà altre modifiche nel CSS e nello script anche nel caso in cui vogliate modificare l'aspetto del menu. Le uniche righe da aggiungere nella sezione head delle pagine che incorporano il menu sono quindi quelle necessarie per incorporare i tre file Javascript, ovvero JQuery, HoverIntent e il piccolo script specifico:

<script type="text/javascript" src="jquery-1.3.2.min.js"></script>
<script type="text/javascript" src="jquery.hoverIntent.minified.js"></script>
<script type="text/javascript" src="jquery-mdd.js"></script>

Questo è tutto per l'aspetto implementativo del menu. Ora è tempo di conclusioni.

Conclusioni

Abbiamo visto in questo appuntamento come realizzare un menu mega-dropdown attraversando le varie
fasi di sviluppo con HTML, CSS e Javascript. La compatibilità dell'esempio finale è decisamente buona: presentazione e funzionalità sono state testate con successo sulle ultime versioni di Firefox, Safari e Google Chrome, oltre che su Internet Explorer dalla versione 6 alla 8. C'è da evidenziare che il menu non funziona su IE6 con Javascript disabilitato, dato che questo browser non supporta la pseudo-classe :hover su qualcosa di diverso dai link.

Per quanto riguarda i browser non supportati, ci tengo a ripetere la raccomandazione di apertura:
bisognerà assicurarsi in casi reali che le voci di primo livello siano link attraverso cui sia possibile raggiungere tutte le possibili sottosezioni anche senza fruire della piena funzionalità del menu: solo in questo modo si potrà garantirantire la piena fruibilità dei contenuti.

Per le risorse sui mega-dropdown, oltre a Mega Drop-Down Navigation Menus Work Well,
segnalo le stupende ispirazioni di Designing Drop-Down Menus: Examples and Best Practices
e il tutorial Make a Mega Drop-Down Menu with jQuery.

Tutti gli esempi qui visti, compresi i file CSS e Javascript, sono disponibili per il download. Alla prossima.

Ti consigliamo anche