Menu multilivello ad albero

Il menu Oggi vorrei parlarti di questo utile quanto simpatico menu ad albero espandibile all’infinito realizzato in HTML CSS e […]
Menu multilivello ad albero

Il menu

Oggi vorrei parlarti di questo utile quanto simpatico menu ad albero espandibile all’infinito realizzato in HTML CSS e jQuery. Da circa 8 mesi ormai sto lavorando per il gruppo Banzai in Sitonline Srl e mi capita molto spesso di imbattarmi in progetti molto interessanti, uno di questi è stato realizzare questo menu per la piattaforma in questione ed ho ritenuto giusto condividerlo con te.

La Parte HTML

Essendo un menu, l’unico modo corretto per realizzarlo è quello di utilizzare liste annidiate, Se non hai una sufficiente esperienza al riguardo, di seguito troverai un listato di codice che ti illustra come fare, altrimenti passa allo step successivo. Il codice HTML inerente ad un semplice menu è il seguente, con l’unica differenza che se vuoi realizzare una lista ordinata, ti basterà usare il tag “ol” al posto di “ul” che rappresenta invece una lista non ordinata:

<ul>
    <li>Prima Voce</li>
    <li>Seconda Voce</li>
    <li>Terza voce</li>
</ul>

Cosa succede se abbiamo necessità di inserire un sottomenu collegato alla seconda voce? Niente di più facile:

<ul>
    <li>Prima Voce</li>
    <li>Seconda Voce
        <ul>
            <li>Seconda Voce I</li>
            <li>Seconda Voce II</li>
            <li>Seconda Voce III</li>
            <li>...</li>
        </ul>
    </li>
    <li>Terza voce</li>
    <li>...</li>
</ul>

Ora che conosci i meccanismi fondamentali delle liste, capirai che un menu del genere è espandibile all’infinito. Bisogna stare solo molto attenti a gestire bene la parte CSS affinchè non ci siano problemi di visualizzazione a causa di un numero non conosciuto di sottoliste.

La parte CSS

Questa parte consiste nella stesura di tutte le regole che concorrono a dare una formattazione visiva al menu. Non analizzerò passo passo tutte quante le regole ma evidenzierò solo i passaggi fondamentali. Il consiglio che vi do è quello di analizzare con firebug il menu mentre illustro i passaggi fondamentali. La struttura ad albero puntinata, come la si vede nella demo, in realtà è molto semplice da realizzare. Tutti gli LI hanno un bordo sinistro di 1px (che tutti insieme concorrono a definire la lunga linea verticale) e un’immagine di sfondo orizzontale che definisce la loro posizione lungo quella linea.

#sidebar ul li {
	background: url("bg_list.gif") no-repeat scroll 2px 18px transparent;
	border-left: 1px dotted #C0CAD4;
}

Ovviamente per ogni last-child ho fatto un piccolo override per elminiare il bordo sinistro e il marcatore di lista, aggiungendo al suo posto un immagine di sfondo di forma ad “L” che andasse a chiudere la lista stessa.

#sidebar ul li.last {
	background: url("bg_list_last.gif") no-repeat scroll -1px 1px transparent;
	border: medium none;
}

Infine per aprire e chiudere le sottoliste, ho inserito un piccolo span cliccabile con classe “plus” affianco a tutti gli LI con una sottolista associata, identificati a loro volta con una classe “open”. Il piccolo span ha come immagine di sfondo uno sprite con due frecce una verso il basso e una verso l’alto. La seconda freccia è facilmente richiamabile con la classe “up” concatenata alla prima

#sidebar ul li .plus {
	background:url("arrowmenu.gif") no-repeat;
	width:8px;
	height:5px;
}
#sidebar ul li .plus.up {
	background-position:0 -5px
}

La parte jQuery

Prova per un attimo a disabilitare l’inclusione di jQuery dal demo, come risultato abbiamo tutto il menu completamente esploso di fronte a noi, senza classi ne span; Quello che dobbiamo fare adesso è:

Rendere invisibili tutti i sottomenu:

$("li > ul").hide();

A tutte le ancore dirette discendenti degli li che hanno una lista associata, aggiungo la classe open per evienziare che hanno sottoliste associate.

$("li:has(ul) > a").addClass("open");

A tutti gli li:last-child diretti discendenti di un ul , attribuisco la classe last (riprendete la parte CSS per capire meglio)

$("#sidebar ul > li:last-child").addClass("last");

Creo dinamicamente un elemento span per aprire i sottomenu. E’ sicuramente preferibile crearlo dinamicanete invece di includerlo nell’html a monte. Per google non ha alcun significato uno span vuoto ripetuto tutte quelle volte nel codice.

$("<span class='plus'></span>").insertAfter(".open");

Questa parte finale gestisce l’apertura e chiusura delle sottoliste. In sostanza al click dell’elemento identificato con lasse “plus”, se l’elemento immediatamente successivo nel DOM a quello cliccato non è visibile allora effettua lo slideDown (effetto tendina), e contemporaneamente per l’elemento con classe plus aggiungi una classe concatenata “up” (richiamata con una funzione anonima di callBack), durante un fadeOut di 200 millisecondi. Altrimenti (else), esegui lo slideUp della sottolista che si trova nel DOM immediamente dopo all’elemento cliccato, e rimuovi la classe up nella stessa modalità di prima.

$(".plus").click(function(){
	if($(this).next().is(":hidden")){
		$(this).next().slideDown();
		$(this).fadeOut(200, function(){
			$(this).addClass("up").fadeIn(); // Durtante il fadeOut aggiungo la classe up e riporto a 1 l'opacità
		});
	} else {
		$(this).next().slideUp();
		$(this).fadeOut(200, function(){
			$(this).removeClass("up").fadeIn(); // Durtante il fadeOut rimuovo la classe up e riporto a 1 l'opacità
		});
	}
});

Riguardati il tutto

Il più è fatto. Adesso non ti resta altro da fare che analizzare meglio il codice css per scoprire tutte le altre regole che concorrono a dare la formattazione visiva al tutto.

Alla prossima ciao!

Provalo subito

Prova la demo Consulta il codice
  • Molto utile, grazie. 😉

  • Pingback: Raccolta di articoli della settimana 23/10/2011 | Saverio Gravagnola()

  • Simone

    Bel menu css… peccato che all’apertura della demo live Kaspersky Pure 2.0 blocca un Trojan. non è simpatico! 😈

    • Ciao Simone, scusaci per l’errore e grazie per avercelo fatto notare. Abbiamo aggiornato la versione di jquery, ora non dovrebbero esserci problemi. 😉

  • fabio

    Ciao, mi piace molto il tuo menu però se uso la classe currentcat in un sottomenu non tiene aperti gli ul “padri”. Come devo fare?

    Grazie

    • Ciao Fabio in realtà non so come mai ci siano quelle istruzioni con riferimento alla “currentcat” nella demo e nel file zip scaricabile. Il tutto funziona in maniera dinamica senza la necessità di implementare la suddetta classe. Mi spiace di aver creato confusione inserendo erroneamente quel blocco di codice nella parte jQuery. Ho provveduto a ricaricare il tutto online eliminando le parti inutili.

      Adesso non dovrebbero esserci piu problemi. Utilizza pure la demo declinandola graficamente come piu ti piace.

      Scusami ancora e grazie a te.

  • Valerio

    ciao! mi piace molto il tuo menu’.
    Come posso fare per lasciare aperte determinate voci di menu’ a seconda di quello che clicco.
    Cioè vorrei avere “memoria” di quello che ho cliccato e aperto, anche aggiornando la pagina voglio avere le voci che ho cliccato aperte…

Search
Tags
Seleziona rubrica
Seleziona rubrica
Codice Github