I menu sono da sempre parte integrante e fondamentale delle pagine web. Con il passare degli anni e grazie alle moderne tecniche CSS e Javascript si è assistito ad un radicale cambiamento di questo componente verso una forma sempre più dinamica e flessibile.
In questo post ti spiego una tecnica molto semplice per realizzare un menu dropdown a tre livelli (ma potrebbero essere a due o più) con il solo uso dei fogli di stile CSS.

I menu a tendina (dropdown menu) imitano in un certo senso il comportamento del tag select (quello che viene spesso usato per inserire la nazione in una form).
Passiamo al codice…
L’unica pecca di questa tecnica, a cui rimedieremo in un post successivo, è la mancata compatibilità con Internet Explorer 6 il quale non supporto la proprietà hover per elementi che non siano i link.
per prima cosa vediamo la struttura dell’html. Si tratta di una semplice lista non numerata con 2 sotto livelli in html:
<div id="menu">
<ul>
<li><a href="#">Menu 1</a>
<ul>
<li><a href="#">Menu 1-1</a></li>
<li><a href="#">Menu 1-2</a>
<ul>
<li><a href="#">Menu 1-2-1</a></li>
<li><a href="#">Menu 1-2-2</a></li>
<li><a href="#">Menu 1-2-3</a></li>
</ul>
</li>
<li><a href="#">Menu 1-3</a></li>
</ul>
</li>
<li><a href="#">Menu 2</a>
<ul>
<li><a href="#">Menu 2-1</a></li>
<li><a href="#">Menu 2-2</a></li>
<li><a href="#">Menu 2-3</a></li>
</ul>
</li>
<li><a href="#">Menu 3</a>
<ul>
<li><a href="#">Menu 3-1</a></li>
<li><a href="#">Menu 3-2</a></li>
<li><a href="#">Menu 3-3</a>
<ul>
<li><a href="#">Menu 3-3-1</a></li>
<li><a href="#">Menu 3-3-2</a></li>
<li><a href="#">Menu 3-3-3</a></li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
Senza applicare stili la resa di questo codice è la seguente:

Applichiamo ora il seguente CSS:
#menu{
padding:0;
maragin:0;
font-family:Verdana,Arial;
font-size:0.70em;
}
#menu ul{
padding:0;
margin:0;
}
#menu li{
position: relative;
float: left;
list-style: none;
margin: 0;
padding:0;
border-bottom: 1px solid #ddd;
border-left: 1px solid #ddd;
}
#menu li a{
width:150px;
height: 30px;
display: block;
text-decoration:none;
text-align: center;
line-height: 30px;
color: #333;
background: #EDEDED;
}
#menu li a:hover{
background: #CCC;
}
#menu ul ul{
position: absolute;
top: 30px;
visibility: hidden;
}
#menu ul li:hover ul {
visibility:visible;
}
#menu ul ul ul li {
visibility: hidden;
left:150px;
top:-30px;
}
#menu ul ul li:hover ul li {
visibility:visible;
}
facendo sapiente uso della proprietà Visibility e dell’attributo hover è possibile rendere visibili le liste in conseguenza al passaggio del mouse sulla lista superiore.
Il risultato che ne consegue è il seguente:

Questa soluzione è stata testata ed perfettamente compatibile con Internet Explorer (esclusa versione 6), Firefox, Safari e Chrome.
AGGIORNAMENTO
In risposta a Frulli aggiungo il CSS necessario per un ‘uteriore livello:
<pre>#menu ul ul ul ul li{
display:none;
left:150px;
top:-30px;
}
#menu ul ul ul li:hover ul li {
display:block;
}
In pratica non fai altro aggiungere un UL ogni volta che utilizzi un sottolivello.
Allego per completezza l’esempio aggiornato da scaricare:
Se stai cercando nuove risorse sui fogli di stile visita il canale CSS di webquadro o puoi abbonarti gratuitamente al feed RSS di webquadro per non perdere nemmeno un articolo.
Se invece vuoi un menu dinamico che faccia uso di javascript prova a seguire questo tutorial: Semplice menu javascript con jQuery
Ecco una lista di altre risorse che potrebbero interessarti:









ciao, innanzitutto complimenti per il css,
fatto davvero bene!
stavo provando ad estenderlo per menu di 3° e 4° livello ma ho dei problemi con l’hover e le proprietà hidden e visible…
mi daresti una mano??
Grazie del commento frulli.
Visto che può essere utile ho aggiornato il post con un secondo esempio che fa uso di un ulteriore livello. Come vedi è molto semplice
Grazie mille, veramente molto utile!
Ciao
molto ben fatta questa lezioncina sui menu a discesa con i css.
Volevo chiederti…
Se io volessi implementarlo facendo aprire le sottovoci della voce “Menu 3-3″ alla sua sinistra anziche alla sua destra come si aprono ora che propietà nel css dovrei aggiungere o modificare?
grazie
simone
basta cambiare la proprietà left della lista interessata (#menu ul ul ul li) da 150px a -150px. Non ho fatto test di compatibilità cross browser ma sembra tenere.
Naturalmente la modifica va apportata anche nelle sottoliste.
ciao mi servirebbe estenderlo a un 5 livello….
ho messo un ul come hai detto ma continua a darmi visibile la tendina di 5 livello. allego il codice css
#menu ul ul ul ul ul li {
display:none;
left:152px;
top:-30px;
}
#menu ul ul ul ul ul li:hover li {
display:block;
}
ti metto il link al sito cosi vedi di che menù si tratta. grazie http://test.clcwebdesigner.it/tps/tecnofluid.html
ciao grazie per il css
stavo provando il menu e volevo far si che le tendine fossero semi trasparenti
mi daresti una mano???
grz
Ciao Flavio,
leggiti questo contenuto:
CSS Opacity
Tieni conto che IE lavora in modo diverso.
Ciao, scusa l’ignoranza, sto incominciando coi css, ma non capisco cosa significa:
#menu ul
cioè #menu crea un id di nome menu coi suoi parametri, ma ul?ù
Ciao grazie per la lezione, molto interessante
L’argomento è abbastanza esteso ma cerco di spiegarlo nel modo più semplice.
# è il selettore. Identifica un elemento in maniera univoca.
).
In questo caso l’elemento si chiama menu e può essere usato una sola volta.
UL sta per unordered list (lista non ordinata o elenco in wordese
Premesso questo…
con questa dichiarazione lo stile viene applicato a tutte le liste non ordinate incluse in un elemento che è stato dichiarato con id menu.
Ti consiglio comunque questa guida che chiarisce questi punti e anche molti altri:
Guida CSS di base
ok grazie più che esauriente.
Salve, avevo una domanda:
Dovrei inserire delle immagini al posto dello stile sui pulsanti, queste immagini hanno dimensioni diverse quindi dovrei creare più tag #menu li con dimensioni diverse di larghezza. Qual’è la giusta sintassi da utilizzare sul css? Come diversificare i diversi #menu li?
Posso risolvere così?
#menu li.primo
e nel codice html
Dando agli elementi della lista li delle classi diverse puoi fare quello che intendi. Naturalmente se le dimensioni sono diverse tra i pulsanti devi rimuovere le dimensioni dall’elemento generico [#menu li] ed attribuirle (insieme all’immagine di sfondo) al sotto elemento [#menu li .nomeclasse]
ho creato un #menu li.primo attribuendo un immagine di sfondo, ma l’immagine si ripete anche sui nei sotto link.
Come posso impostare un immagine solo nella barra principale e lasciare inalterati i sotto link?
Essendo figli del menu principale ereditano le proprietà del padre.
Devi impostare nuovamente il background negli elementi figli [#menu li li] o prova semplicemente con [background-image:none;]
Maurizio c’è un modo più diretto per potrerti contattare? skype msn… se per te non è un problema!
Penso che debba creare degli elementi figli per ogni sigolo elenco ma ho paura di sbagliare qulcosa, al momento quello che ho in css è questo:
[RIMOSSO]
Usa Skype. Il link lo trovi in fondo alla pagina!
ciao Maurizio,
ho visto il tuo menù dropdown, mi piace molto e vorrei utilizzarlo nel mio sito, solo che il lato html, vorrei che si integrasse con le select sql, prelevate dal database access. Potresti darmi una mano a riguardo??? posso contattarti tramite skype!
Grazie
Ciao Tatiana, mi dispiace ma sono completamente a digiuno di Access quindi non saprei proprio da dove partire.
salve ho visto questo css e devo dire che e ben costruito sarebbe un sogno chiedere di farlo funzionare su exsplorer??…quando la gente capira che ex deve chiudere e fire fox se lo deve mangiare i figli dei miei figli saranno pelati!!
il problema è Internet Explorer 6 che non sopporta l’attributo “hover” per elementi diversi dai link. In questo menu si fa uso di hover sulle liste (li).
L’unico modo per farlo funzionare è lavorare con un javascript che attivi la visibilità del sottomenu al posto del css al passaggio del mouse…
Ciao e scusa una domanda,
faccio l’esempio dei programmi di grafica: quando io inserisco un’immagine, per esempio in InDesign, questo mi crea un collegamento all’immagine; così se io modifico l’immagine, automaticamente indesign la aggiorna modificata. Io potrei fare lo stesso con il tuo menu a tendina (ossia genstirlo come file esterno modificandolo di volta in volta, aggiungeno o togliendo varie tendine, così da aggiornarsi automaticamente su tutte le pagine dove è inserito?)
Io userei il tuo menù per un sito di provini fotografici paesaggistici, e ogni volta che aggiungo una località dovrei andare a modificare tutti i menu di tutte le pagine… megli il suicidio.
Ti ringrazio
Il menu che propongo si basa su una struttura classica (le liste UL). Tutto il funzionamento è creato grazie agli stili applicati a questi elementi a prescindere da quanti sono.
Quindi hai bisogno di un sistema che generi il codice necessario in automatico senza problemi.
Nel tuo caso specifico un sito statico non sembra la soluzione migliore perché prevedi aggiornamenti frequento.
Ti conviene virare per qualche CMS (io consiglio sempre Wordpress) che sul medio lungo periodo ti permetterà di risparmiare un sacco di tempo.
ciao!!
stra utile il tuo css! xò mi chiedevo, se ad esempio al posto di “menu 1-1″ ci voglio scrivere qualcosa di un po più lungo, come posso ridimensionare il menu a tendina?? perchè ho provato un pochino ma niente…mi si ferma a metà scritta…magari se si potrebbe allargare il box!
ancora bravissimo!!
devi modificare la proprietà width della classe “#menu li a”. I sotto menu andranno spostati di conseguenza agendo sulla proprietà left.
in pratica metti su tutti i left che trovi lo stesso valore che hai impostato per il width della classe che ti dicevo sopra. Ora sono tutti settati a 150px
mmm si perfetto! ma se io vorrei lasciare il menu così come sta??? e magari solo allargare il sottomenu?? così facendo mi allarga tutto o no?
Si può fare ma diventa molto più complicato. Tutte le modifiche che uno può fare dipendono dalla conoscenza dei css.
allora ti spiego…io ho impostato solo il primo sottomenu….quindi cancellando il “menu 1-2-1″ e tutti gli altri…ho modificato un po il css…xò quando provo a modificare quello li nn va, proprio nn riesco!! mi escono i sottomenu affianco nn più larghi!
Eccomi qua!
Innanzitutto, come al solito, complimenti per l’ottimo lavoro svolto.
Mi domandavo dove andare a “mettere le mani” per rendere questo menu un “drop line”, di quel tipo cioe’ in cui basta fare “hover” su una voce della barra del menu per veder apparire la barra di secondo livello, posizionata sotto la barra di primo livello o anche al di sopra di essa.
In alternativa, potrei utilizzare anche questa stessa versione, purche’ pero’ le tendine andassero verso l’alto e non verso il basso.
Grazie, Marco.
Scusami Marco ma mi ero “perso” il tuo commento
Non sono sicuro di aver capito cosa stai cercando di realizzare ma prova a dare un’occhiata a questo menù che ho proposto qualche mese fa:
http://www.webquadro.it/2010/03/semplice-menu-javascript-con-jquery/