In questo thread vorrei illustrare la strada più semplice che ho trovato per realizzare la struttura in oggetto: ovvero un menu orizzontale che abbia una barra verticale (o pipe) di separazione tra ciascuna voce, ma non agli estremi, cioè
codice:
voce menu 1 | voce menu 2 | ... | voce menu n
Premessa: sebbene un menu di questo tipo preveda di norma un'unica struttura costituita da una lista non ordinata <ul>[*] ci sono molti modi per realizzare le pipe di separazione, tuttavia alcuni sono scorretti, altri non ottimizzati
L'errore più comune è inserire il pipe alla fine delle varie voci (dopo il tag </a> e prima del tag ) o, peggio ancora, inserirli in una voce di menu dedicata, del tipo
Questa soluzione poi, oltre a essere scorretta da un punto di vista semantico (le barre sono elementi della formattazione/presentazione, non del contenuto) spesso introduce complessità poichè, conseguenza naturale, sarà l'introduzione di classi specifiche sugli[*] per dare la giusta spaziatura tra le voci.
Una soluzione più corretta potrebbe prevedere la generazione delle barre verticali attravero la proprietà css border da applicare agli[*], ad esempio impostando il bordo destro o sinistro. In questo modo però le barre non saranno presenti solo tra le voci ma, a seconda di quale bordo è stato usato, saranno presenti anche all'inizio o alla fine:
esempio con border-left su[*]
codice:
|voce menu 1 | voce menu 2 | ... | voce menu n
esempio con border-right[*]
codice:
voce menu 1 | voce menu 2 | ... | voce menu n |
Spesso si ovvia a questa situazione introducendo una classe sulla prima (o sull'ultima voce) attraverso la quale azzerare il relativo bordo.
Il più delle volte può andare bene, ma se il nostro template prevede di essere integrato lato server, in un contesto in cui le voci vengono generate dinamicamente, identificare la prima o l'ultima voce comporta l'uso aggiuntivo di codice (lato server) per fare un controllo extra sul numero di voci.
Se per molti questo problema può sembrare banale, potrebbe non esserlo per chi dovrà montare il template per essere dinamicizzato. Inoltre personalmente non mi piace l'idea di dover usare una classe apposita che assolva solo a questa funzione specifica.
A partire da queste considerazioni (di cui mi scuso per la verbosità) propongo quindi la mia personale soluzione semanticamente corretta e che non necessita di classi aggiuntive per identificare uno dei list-item agli estremi.
Il codice che vi propongo non ha particolari complessità e basa il suo funzionamento sul clearing della lista <ul> che quasi sempre viene "dimenticata" su questo tipo di menu. Quindi i list-item vengono spostati indietro di 1px (se la barra deve essere larga "n" pixel allora il margin-left vale "-n" pixel) causando lo scorrimento delle voci verso sinistra e nascondendo la prima barra verticale.
codice:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="it" xml:lang="it">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Liste con barre verticali di separazione</title>
<style type="text/css">
/** stile generale **/
body {
font : 10px Verdana, Arial, sans-serif;
}
ul {
list-style-type : none;
margin : 0;
padding : 0;
border : 1px solid #c00;
height : auto;
overflow : hidden;
}
li {
float : left;
display : inline;
}
/** stile specifico li **/
li {
border-left : 1px #4a4a4a solid;
padding : 0 10px;
margin-left : -1px;
}
</style>
</head>
<body>
<ul>[*]Voce elenco 1[*]Voce elenco 3[*]Voce elenco 4[*]Voce elenco 5[/list]
</body>
</html>
Per rendersene conto è sufficiente eliminare le proprietà overflow e height dall'elemento <ul>. Il bordo rosso è applicato solo per vedere gli effetti della presenza di queste regole specifiche, può essere omesso.
Testato su IE6, IE7, Firefox 2 (mac/pc), Safari 2.0.4. Se si desidera la compatibilità anche con IE5.5 si effettui un clearing con la tecnica dell'easyclearing o equivalente.