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

Menu dropdown in stile Facebook

Realizziamo con i soli CSS un menu a tendina simile a quello del celebre social network
Realizziamo con i soli CSS un menu a tendina simile a quello del celebre social network
Link copiato negli appunti

Dopo un menu in stile Vista e
l'accordion in stile Apple
torniamo sulla serie delle ispirazioni con un articolo credo molto atteso dai lettori di HTML.it, dato che
non ho ancora mai trattato l'argomento dei menu dropdown nei molti articoli della sezione CSS.

Considerando la vastità dei concetti qui trattati, questo articolo sarà suddiviso in due parti.
Nella prima parte vedremo l'idea di base e arriveremo a realizzare un menu in stile Facebook già
totalmente operativo su Internet Explorer 7 e superiori, oltre che sulle ultime versioni
di Opera, Firefox, Safari e Chrome. Nella seconda parte vedremo diverse soluzioni per
estendere il supporto su IE6 e IE5.5 e migliorare l'usabilità del menu
anche nei browser più moderni.

Possiamo procedere, non senza qualche raccomandazione di carattere generale che consiglio
di considerare prima di implementare una delle soluzioni che vedremo nel corso di questo articolo.

Ci sono sostanzialmente tre regole da tenere in conto se si vuole implementare
in maniera efficace e accessibile un menu dropdown. La prima, e la più importante,
è che le voci principali del menu dovranno essere link, attraverso i quali sia possibile
accedere ad altre pagine che presentano in qualche modo e in un posto diverso dal menu stesso
le sottovoci del menu. Questo per garantire la fruibilità del sito a chi naviga con browser obsoleti
e dispositivi mobili ad esempio. Seguendo il primo punto, siamo sicuri inoltre di realizzare un sito
che sia possibile navigare anche in assenza di Javascript. Infine è importante una
compatibilità cross-browser estesa al massimo
così da fornire la migliore esperienza di navigazione al maggior numero di utenti.

Un menu dropdown in stile Facebook

Dopo questa breve introduzione, siamo pronti a presentare l'esempio base che apre
l'articolo: si tratta di un menu a tendina palesemente ispirato da Facebook, il noto
sito di social networking tanto in voga ultimamente. A beneficio dei lettori che non
sono iscritti, riporto uno screenshot del menu che si presenta nella pagina principale
di Facebook una volta effettuato il login:

Figura 1 - Screenshot del menu di Facebook
screenshot del menu di Facebook

Vedremo il procedimento di realizzazione dell'esempio di base
attraverso le due fasi principali, ovvero l'HTML e il CSS. Cominciamo.

L'HTML del menu

L'HTML del nostro menu a tendina è composto da
una semplice lista annidata, in cui le voci principali sono racchiuse da elementi strong
così da risultare in evidenza. Vediamo il codice:

<ul id="nav">
<li>
    <a href="#"><strong>Home</strong></a>
</li>
<li>
    <a href="#"><strong>Mail</strong></a>
    <ul>
        <li><a href="#">Compose mail</a></li>
        <li class="sep"><a href="#">Inbox</a><span></span></li>
        <li><a href="#">Sent mail</a></li>
        <li><a href="#">Spam</a></li>
    </ul>
</li>
<li>
    <a href="#"><strong>Settings</strong></a>
    <ul>
        <li class="icon settings"><a href="#">Account settings</a></li>
        <li class="icon privacy"><a href="#">Privacy settings</a></li>
    </ul>
</li>
</ul>

Come si può notare, il markup ricalca perfettamente la semantica del menu: in
assenza di fogli di stile infatti la struttura a livelli del menu rimane intatta:

Figura 2 - Il menu in assenza di CSS
lista annidata

A questo punto non ci resta che procedere con il CSS dell'esempio,
che non risulta troppo complesso. Per fissare il concetto principale, è importante
però servirsi di un esempio intermedio che è costituito solo dalle dichiarazioni
essenziali per ottenere un menu dropdown minimale ma allo stesso tempo funzionale.

I concetti di base dei menu dropdown

Mettiamo quindi un attimo da parte il nostro esempio pilota
per presentare l'esempio "zero", un menu dropdown funzionale
e graficamente scarno che racchiude però i concetti essenziali degli altri esempi che vedremo:

Figura 3 - Il menu dropdown minimale
screenshot

Da evidenziare che è costituito dallo stesso markup degli altri esempi
e presenta una versione ridotta del foglio di stile. Per quanto riguarda il CSS,
si procede innanzitutto a eliminare margini, padding e marcatore da liste e list-item,
oltre che a definire l'altezza di linea del menu e gli stili di base dei link:

ul#nav,ul#nav li,ul#nav ul{margin: 0;padding: 0;list-style: none;line-height: 1.8em}
ul#nav a{display: block;padding: 0 1em;text-decoration: none;color:#3B5998}
ul#nav a:hover{color: #121B36}

Quella che segue è la parte principale del nostro menu minimale:
in sostanza si tratta di affiancare i list-item di primo livello rendendoli float e posizionarli
relativamente. Dovremo però aver cura di annullare l'effetto dei float sui list-item di secondo livello,
grazie ad una regola più specifica:

ul#nav li{float: left;position: relative}
ul#nav li li{float: none}

I list-item principali creano così un contesto di posizionamento, e grazie ai
posizionamenti assoluti
siamo in grado di sistemare rispetto ad essi le liste di secondo livello.
I sottomenu verranno inizialmente nascosti, o meglio traslati dallo
schermo grazie alla tecnica off-left,
per poi essere mostrati ripristinando la proprietà left sul valore "auto"
solo in fase hover dei list-item principali. Ecco le due regole:

ul#nav ul{position: absolute;top: 1.7em;left: -9999px;width: 12em}
ul#nav li:hover ul{left: auto}

Con sole sette regole, abbiamo un menu dropdown funzionale sui browser moderni.
Nel caso vorrete realizzare un menu a tendina, ma magari non vi piace l'aspetto degli esempi di questo articolo,
questo potrebbe essere un buon punto di partenza.

Il CSS dell'esempio pilota

Partendo dall'esempio minimale che abbiamo appena illustrato, non è difficile
arrivare al nostro esempio pilota: si tratta
a questo punto di definire i colori di sfondo e del testo, i bordi e affinare le spaziature
(altezza e line-height) dei vari elementi. Le regole principali per il nostro menu
da sette diventano undici, anche se ovviamente presentano un numero maggiore di dichiarazioni.
Eccole:

ul#nav{font: 70%/1.5 Verdena,Tahoma,sans-serif}
ul#nav,ul#nav li,ul#nav ul{margin:0;padding:0;list-style:none}
ul#nav{height:26px;line-height:25px;margin-left:50px;
    background: #3B5998;color: #fff}
ul#nav a{display:block;padding: 0 15px;text-decoration: none; color:#FFF}
ul#nav li{float: left;position: relative}
ul#nav li li{float: none;line-height: 22px;
    display:block !important;display: inline; /*IE*/}
ul#nav ul{position: absolute;top: 23px;left: -9999px;
    width: 12em;background: #fff;color: #3B5998}
ul#nav ul{padding: 7px 0;border: 1px solid #3B5998}
ul#nav ul,ul#nav li li a{background-color: #FFF;color: #3B5998}
ul#nav li:hover,ul#nav a:hover{background-color: #5C75AA;color: #FFF}
ul#nav li:hover ul,ul#nav li.sfhover ul{left: -1px;z-index: 100}

Nel CSS dell'esempio ci sono poi alcune regole per due caratteristiche
addizionali del menu che sono presenti anche nel menu a tendina di Facebook. La prima
riguarda il separatore tra due list-item, di cui riporto uno screenshot:

Figura 4 - Il separatore tra list-item
screenshot

Nel markup dell'esempio, al list-item che precede
il separatore viene assegnata una classe "sep" e uno span
vuoto viene inserito dopo il link al suo interno:

<li class="sep"><a href="#">Inbox</a><span></span></li>

Questo list-item verrà reso più alto, e lo span rappresenterà la linea di separazione.
Basterà renderlo display:block e alto 1px, avendo cura di regolare i margini:

ul#nav li.sep{height: 34px;background: #fff}
ul#nav li.sep span{display: block;height: 1px;overflow: hidden;
    margin: 6px 5px 0;background: #CCC}

Da notare che ci sono moltissimi modi per ottenere un effetto simile e alcuni
di essi non richiedono lo span aggiuntivo. Ma per praticità e per garantire un
ampio supporto dell'effetto, ho preferito usare lo span: va precisato che
tale elemento non incide sulla presentazione di default (essendo per sua
natura inline) nè sul contenuto, essendo vuoto. Ad esempio, una
soluzione più elegante, ma con minore supporto cross-browser,
potrebbe eliminare lo span e usare i
contenuti
generati
. La seconda regola diverrebbe quindi:

ul#nav li.sep:after{content: "";display: block;height: 1px;overflow: hidden;
    margin: 6px 5px 0;background: #CCC}

Altra caratteristica accattivante del menu dropdown, anch'essa presa
in prestito da Facebook, è l'uso delle icone su alcune voci:

Figura 5 - Uso delle icone
screenshot

In questo caso è bastato usare le classi multiple nel markup, come abbiamo
fatto ad esempio nei messaggi di alert,
le icone che provengono dal set free Mini Icons, e un paio di regole aggiuntive nel CSS:

ul#nav li li.icon a{padding-left: 24px}
ul#nav li li.settings a{background: url(icon_settings.gif) no-repeat 3px 3px}
ul#nav li li.privacy a{background: url(icon_padlock.gif) no-repeat 3px 3px}

Da evidenziare come nello shorthand background non figura la parte
relativa al colore: questa viene infatti specificata per lo stato normale e hover
attraverso la proprietà background-color.
Il nostro esempio di base è così ultimato: con un numero relativamente limitato
di regole abbiamo ottenuto un menu dropdown piacevole e robusto sui browser moderni:
è stato testato con successo su IE7 e la beta 2 di IE8, oltre che sulle versioni
più recenti di Opera, Firefox, Safari e Google Chrome.

I sottolivelli non vengono invece mostrati su Internet Explorer 5.5 e 6, dato
che questi due versioni del browser Microsoft non supportano la pseudo-classe :hover
su elementi diversi dai link. Per poter utilizzare un menu simile su una pagina
web allo stato attuale, dovremo garantire la compatibilità quantomeno su IE6,
che conta una percentuale di utilizzo ancora molto significativa, tra il 20 e il 35%
in Ottobre 2008 secondo alcuni servizi di statistiche globali consultabili online.

Ci sono moltissime strategie per estendere il supporto del nostro menu: ne vedremo
alcune nella seconda parte tra una settimana. Per il momento potete scaricare gli esempi fin qui visti per una più comoda consultazione.

Usare gli HTC per li:hover

Apriamo la sezione dedicata ad estendere la compatibilità di base del
nostro menu con una soluzione proprietaria di Internet Explorer.
I behaviour offrono un
modo per attribuire mediante JScript il comportamento di elementi individuati da selettori CSS.
Risale al 2005-2006 la soluzione whatever:hover di Peter Nederlof
per estendere la compatibilità della pseudo-classe :hover in Internet Explorer 5.5 e superiori.
Il tutto viene fatto in maniera trasparente e senza la necessità di aggiunte nel CSS.

Il CSS principale di questo secondo esempio resta quindi identico all'esempio di base.
Attraverso un commento condizionale , viene inserito nella pagina
un CSS specifico volto a IE6 e inferiori:

<!--[if lte IE 6]>
<link rel="stylesheet" type="text/css" href="iefix-htc.css">
<![endif]-->

Il file iefix-htc.css contiene in realtà un'unica regola, che serve a poter assegnare la pseudo-classe :hover
al body grazie all'uso degli HTC:

body { behavior:url("csshover.htc")}

Tra le virgolette andrà specificato il nome del file HTC, con eventuale percorso, che dovrà
essere caricato sul server per far si che il nostro menu dropdown possa funzionare a dovere anche su IE6 e IE5.5
oltre che sui browser su cui non ha problemi la versione di base.
Con questa piccola aggiunta, la compatibilità del menu si è estesa di molto:
da IE5.5 fino alla beta 2 di IE8, oltre che sulle ultime versioni di Firefox, Opera, Safari e Chrome.

Risale ormai a cinque anni fa l'articolo Suckerfish Dropdown
pubblicato su Alistapart, che presenta un modo semplice per estendere con javascript e una regola CSS aggiuntiva
la funzionalità dei menu dropdown anche ai browser non capaci di interpretare correttamente la pseudoclasse :hover
sui list-item. L'autore Patrick Griffiths ha poi ripreso e migliorato la tecnica e lo script in Son
of a Suckerfish
, che conta appena dodici linee di javascript.

Ecco quindi il terzo esempio, che presenta lo stesso supporto dell'esempio di base
e lo estende anch'esso a IE5.x e IE6.In questo caso l'unica aggiunta da fare è linkare lo script, ancor meglio se
attraverso un commento condizionale:

<!--[if lte IE 6]>
<script type="text/javascript" src="suckerfish.js"></script>
<![endif]-->

Da evidenziare poi che per il corretto funzionamento dello script, il blocco dichiarativo
di li:hover andrà duplicato nel CSS con l'uso della classe "sfhover", che verrà aggiunta
al volo da Javascript. Vediamo le regola interessata:

ul#nav li:hover ul,ul#nav li.sfhover ul{left: -1px;z-index: 100}

Questa soluzione si presenta semplice e ha la
stessa compatibilità del secondo esempio, ha forse il pregio di richiedere un file
solo (il Javascript) e di avere un approccio un po' più standard, anch'esso confinato in un commento
condizionale. Se cinque anni fa infatti i browser che richiedevano una piccola
spinta mediante javascript erano diversi, ora restano solo più
le vecchie versioni di Internet Explorer.

Siamo così arrivati agli ultimi due esempi dell'articolo, che
usano un approccio un po' più moderno e dei risultati efficaci grazie
alla famosa libreria Javascript. In questo caso l'uso di JQuery
ha un duplice scopo: estendere la funzionalità del menu dropdown a IE6
(rimane escluso IE5.x che non è supportato da JQuery) e aggiungere un'accattivante
transizione a scorrimento, anche sui browser più moderni.

Nel nostro quarto esempio
viene aggiunta la libreria JQuery (ho usato la versione 1.2.6 minimizzata, ovvero la più recente
al momento in cui scrivo) e lo script specifico per il nostro menu, che consente un effetto
a scorrimento. Ecco il codice che va aggiunto nella sezione head:

<script type="text/javascript" src="jquery-1.2.6.pack.js"></script>
<script type="text/javascript" src="jquery-dd.js"></script>

Il contenuto del file jquery-dd.js è di appena cinque righe, e si occupa di
assegnare le transizioni al passaggio del mouse sui list-item. Chi non è pratico di
Javascript non ha da preoccuparsi: basterà usare un id="nav" per il
menu e il file Javascript non necessiterà di modifiche. Per gli altri lettori,
ecco il contenuto del file Javascript specifico:

$(function(){
$("#nav>li").hover(
    function(){$("ul",this).slideDown("slow");},
    function(){$("ul",this).css({left:"-1px"}).slideUp("fast");});
});

Rispetto a questo quarto esempio c'è un ulteriore
miglioramento che possiamo introdurre, ovvero l'uso del plugin hoverIntent.
Questo plugin è in grado di intercettare gli eventi del mouse e "capire" le intenzioni dell'utente:
se si passa accidentalmente o molto velocemente sopra una voce del menu, il sottomenu non verrà mostrato,
dato che è necessario un breve tempo di attesa e una velocità del mouse ridotta per attivarlo. Si tratta
a parer mio di un notevole incremento dell'usabilità, come tra l'altro succede sul menu
originale di Facebook.

Ecco quindi il nostro quinto esempio, in cui viene inserito nella sezione head oltre a JQUery e
al piccolo script specifico, anche il plguin hoverIntent:

<script type="text/javascript" src="jquery-1.2.6.pack.js"></script>
<script type="text/javascript" src="jquery.hoverIntent.minified.js"></script>
<script type="text/javascript" src="jquery-ddi.js"></script>

In questo quinto esempio si noterà che la transizione è sull'opacità invece che sull'altezza del menu.
Per il resto, le differenze sullo script specifico rispetto all'esempio precedente sono
davvero minime: si tratta infatti di rimpiazzare la funzione hover con hoverIntent.
Ecco il codice:

$(function(){
$("#nav>li").hoverIntent(
    function(){$("ul",this).fadeIn("slow");},
    function(){$("ul",this).css({left:"-1px"}).fadeOut("fast");});
});

Per il plugin, è stato impostato nel sorgente un'attesa di 250 millisecondi prima di far scomparire la voce aperta del menu
dal momento in cui l'utente allontana il mouse. Per completezza, ho preparato anche un
sesto esempio in cui viene usato insieme all'hoverIntent l'effetto tendina sul menu.

Conclusioni e download

Abbiamo visto il processo di sviluppo di un menu dropdown ispirato a Facebook, partendo dall'approccio
puramente CSS fino ad esplorare diverse soluzioni per estendere il supporto alle vecchie versioni di Internet Explorer
e aggiungere transizioni accattivanti.

Tutti gli esempi visti hanno una buona compatibilità sui browser moderni:
sono stati testati con successo su IE7, IE8 e le ultime versioni di Opera, Safari, Firefox e Google Chrome.
Il secondo e il terzo esempio sono compatibili anche con IE5.5 e IE6, mentre gli ultimi due che utilizzano JQUery
non sono funzionali su IE5.x. Si tratta di un browser decisamente obsoleto, la cui diffusione allo stato attuale
è di pochi punti percentuale, e si può tralasciare senza problemi con gli accorgimenti indispensabili citati in apertura.

Ho voluto esplorare in questa sede le diverse possibilità di implementazione, ma vorrei lasciare al lettore
la libertà della scelta della strategia da utilizzare. Gli esempi completi di codice e immagini sono disponibili
per il download. Alla prossima.

Ti consigliamo anche