Negli esempi di questo articolo verrano illustrate due tecniche fondamentalmente diverse per raggiungere un risultato simile. Partiamo dal presupposto di voler realizzare un menu a tab e centrato orizzontalmente nella finestra del browser, attraverso una struttura XHTML classica realizzatata con una lista non ordinata (<ul>
), assicurandone la resa cross-browser senza utilizzare hack CSS, regole non standard (display:inline-block
è un esempio), o peggio, Javascript.
Voglio ricordare in proposito alcune risorse meritevoli di menzione: l'articolo di Alessandro Fulciniti tab grafiche centrate, e due versioni delle Sliding Doors, Centered Sliding Doors Menus da Explodingboy, e 100% clickable Sliding doors - centered da CSSPlay, che propongono degli esempi di menu centrati con tab ad angoli arrotondati che però utilizzano degli hack per ottenere la compatibilità con le diverse e capricciose versioni di Internet Explorer.
Primo esempio
Nella creazione di una barra di navigazione centrata l'approccio più ovvio (e quindi anche forse più diffuso) prevede di centrare degli elementi, come nel caso delle voci di un menu, di dimensioni non note a priori, attraverso le regole CSS display:inline
(applicata su di essi) e text-align:center
(applicata al loro contenitore). Vediamo subito la struttura HTML base necessaria:
<div id="navigation"> <ul> <li><a href="#" title="home">Home</a></li> <li><a href="#" title="profilo">Profilo</a></li> <li><a href="#" title="notizie">Notizie</a></li> <li><a href="#" title="porfolio">Portfolio</a></li> <li><a href="#" title="prodotti">Prodotti</a></li> <li><a href="#" title="blog">Blog</a></li> <li class="last"><a href="#" title="contatti">Contatti</a></li> </ul> </div>
Come abbiamo già detto, per affiancare le voci del menu utilizzeremo su di esse la dichiarazione display:inline
, evitando accortamente l'utilizzo dei float, cosa che ci consente una agevole e robusta centratura applicando la dichiarazione text-align:center
direttamente sull'elemento <ul>
.
Diversamente, utilizzando proprio la proprietà "float:left" per affiancare le voci della lista, l'unico modo per centrare il menu è assegnare una larghezza definita e la proprietà margin:0 auto
all'elenco non ordinato. Una soluzione comunque imperfetta: pensiamo a quali disastri potrebbe provocare un eventuale ingrandimento del testo da parte dell'utente. Inoltre l'applicazione di un tale metodo non si dimostra nemmeno flessibile, di fronte alla necessità di incrementare il numero delle tab saremo ad esempio per forza di cose costretti a variare anche la width dell'elenco.
Torniamo piuttosto sui nostri argomenti cominciando ad analizzare più in dettaglio gli stili CSS e il parziale risultato nella pagina di prova:
body { margin:0; padding:0; background:#FFFFFF; color:#000; font-family:Arial, Helvetica, sans-serif; font-size:85%; } #navigation { background:#7FAACA url(bg-nav.jpg) repeat-x; border-bottom:1px solid #999999; } #navigation ul, #navigation ul li { list-style:none; margin:0; padding:0; } #navigation ul { text-align:center; padding:0.5em 0; } #navigation ul li { display:inline; margin-right:0.5em; } #navigation ul li.last { margin-right:0; } #navigation li a { padding:0.5em 1em; background:#FFFF00; }
Possiamo dire di essere a metà dell'opera, avendo già ottenuto la centratura del menu di navigazione: da osservare che le varie tab sono distanziate tra di loro del valore attribuito alla proprietà margin-right
. L'ultima voce della lista non ordinata dispone di una classe last proprio per azzerare tale margine non più necessario. Non essendo possibile attribuire una height specifica agli elementi inline, l'unico modo di intervenire sulle dimensioni delle ancore per dar loro la consistenza del pulsante di una tab ci è dato dalla proprietà padding. Per un corretto contenimento verticale del menu è necessario applicare gli stessi valori di padding-top e padding-bottom direttamente anche sull'elemento genitore <ul>
. nell'esempio appena visto viene assegnato un colore di sfondo giallo sui collegamenti solo a scopo dimostrativo, che verrà rimosso negli stili succesivi. Non rimane che creare le tab vere e proprie personalizzando l'aspetto grafico dei link. Controlliamo le regole CSS che è necessario aggiungere prima di vedere l'esempio completo in opera:
#navigation { /* stili precedenti */ padding-top:2em; } #navigation ul li a { background:#FFFFFF url(bg-tab.jpg) repeat-x; color:#0033FF; border-color:#999999; border-style:solid; border-width:1px 1px 0 1px; text-decoration:none; padding:0.5em 1em; } #navigation ul li a:hover { color:#003366; background:#FFFFFF; } #navigation ul li a.active, #navigation ul li a.active:hover { color:#FFFFFF; background:#BCBCBC; }
Da osservare l'inserimento di un padding-top
alla barra di navigazione, per distanziare le tab dal suo margine superiore: è stata anche aggiunta una classe active per evidenziare la tab selezionata. Due le immagini di background utilizzate: una per la barra di navigazione e una per le tab. Naturalmente è possibile modificare a piacimento gli stili applicati agli stati dei link in base alle proprie preferenze.
Secondo esempio
Il secondo esempio dell'articolo prevede un approccio veramente originale, rendendo flottanti gli elementi della lista e centrando
poi la barra di navigazione attraverso un intelligente uso della proprietà position. L'articolo originale di questa tecnica è Beautiful Horizontally Centered Menus/Tabs/List. No CSS hacks. Full cross-browser di Matthew James Taylor. Per cominciare possiamo utilizzare la stessa struttura HTML dell'esempio della tecnica precedente.
La realizzazione di questo menu parte dal principio che un elemento flottante con width non assegnata assume una larghezza pari al suo contenuto: il trucco per ottenere la centratura è posizionare relativamente degli elementi flottanti l'uno all'interno dell'altro. Incominciamo nel costruire un semplice barra di navigazione allineata a sinistra. Ho predisposto un esempio e per meglio evidenziare gli elementi, ho utlizzato le seguenti regole CSS:
#navigation { float:left; width:50%; background:#fff; border:4px solid #006699; margin:15px 0; } #navigation ul, #navigation ul li { list-style:none; margin:0; padding:0; } #navigation ul { clear:left; float:left; margin:10px; border:4px solid #CC0000; } #navigation ul li { display:block; float:left; margin:10px; border:4px solid #009900; } #navigation ul li a { display:block; margin:5px; padding:10px; border:4px solid #FFCC00; text-decoration:none; }
- Il div#navigation, con bordo blu, è flottante a sinistra, con una larghezza del 100%.
- La lista non ordinata (ul), con bordo rosso, è contenuta nel div#navigation ed è anch'essa flottante a sinistra, senza una width specificata. Questo significa che si dimensiona in base alla larghezza del suo contenuto, che è data a sua volta dalla somma delle larghezze di tutte le tab.
- Tutti gli elementi della lista (li), con bordo verde, sono contenuti nell'ul e sono anch'essi flottanti a sinistra e affiancati orizzantalmente. Ogni li assume la larghezza del link in esso contenuto.
- All'interno di ogni link (a), con bordo giallo, è inserito il testo descrittivo delle varie voci del menu: home, profilo, porfolio, etc.
Il passo successivo è quello cruciale, cioè centrare l'elemento ul nel div#navigation: per fare questo assegnamo ad entrambi gli elementi la regola position:relative
, e spostiamo a destra la lista non ordinata del 50% (left:50%
). Vediamo l'esempio parziale. In questo modo l'elemento ul viene spostato verso destra della metà della larghezza del div#navigation. Non rimane che spostare la posizione di tutte le voci del menu verso sinistra del 50% (che rappresenta la metà della larghezza del loro elemento genitore ul), assegnando ad ogni elemento li le regole position:relative
e right:50%
. Ecco l'ulteriore esempio e le regole CSS aggiornate:
#navigation { position:relative; float:left; width:100%; background:#fff; border:4px solid #006699; border-width:4px 0; margin:15px 0; } #navigation ul, #navigation ul li { list-style:none; margin:0; padding:0; } #navigation ul { position:relative; left:50%; clear:left; float:left; margin:10px 0; border:4px solid #CC0000; } #navigation ul li { position:relative; right:50%; display:block; float:left; margin:10px; border:4px solid #009900; } #navigation ul li a { display:block; margin:5px; padding:10px; border:4px solid #FFCC00; text-decoration:none; }
Abbiamo praticamente quasi finito il lavoro "sporco". E' necessario fare però una annotazione: dall'esempio precedente possiamo notare la inattesa comparsa della scrollbar orizontale nella pagina, dovuta al fatto che l'elemento ul è posizionato in modo da eccedere la larghezza del viewport, cioè della parte visibile della finestra del browser. Bisogna quindi sempre applicare la regola overflow:hidden
al div contenitore del menu (in questo caso al div#navigation).
Una volta rimossi i bordi colorati e i margini degli elementi inseriti solo a scopo di debug, possiamo concentrarci sui dettagli più puramente estetici, per conferire un aspetto più gradevole al menu. Poichè l'elemento ul non è allineato con gli elementi che contiene, non è possibile aggiungere stili di presentazione ad esso; si può però intervenire a piacimento sugli elementi li ed a. Non avendo molta fantasia, ho pensato di riutilizzare parte degli stili dell'esempio della prima tecnica illustrata, sicchè il risultato finale è molto simile. Di seguito il CSS completo del menu:
#navigation { position:relative; float:left; width:100%; background:#7FAACA url(bg-nav.jpg) repeat-x; border-bottom:1px solid #999999; padding-top:2em; } #navigation ul, #navigation ul li { list-style:none; margin:0; padding:0; } #navigation ul { position:relative; left:50%; clear:left; float:left; margin:0; } #navigation ul li { position:relative; right:50%; display:block; float:left; } #navigation ul li a { display:block; margin:0 0.25em; padding:0.5em 1em; color:#0033FF; border-width:1px 1px 0 1px; border-color:#999999; border-style:solid; background:#FFFFFF url(bg-tab.jpg) repeat-x; text-decoration:none; } #navigation ul li a:hover { color:#003366; background:#FFFFFF; } #navigation ul li a.active, #navigation ul li a.active:hover { color:#FFFFFF; background:#BCBCBC; }
Anche in questo caso è possibile evidenziare la tab selezionata assegnandole una classe active creata ad hoc. Inoltre, sempre tramite l'aggiunta di classi apposite stavolta applicate sugli elementi li, si può differenziare l'aspetto della prima e dell'ultima voce del menu. Visitando la pagina degli esempi avanzati nel blog dell'autore sono disponibili diverse implementazioni grafiche di questa tecnica; alcune barre di navigazione sono anche più accattivanti delle "semplici tab".
Conclusioni
Attraverso le tecniche precedentemente illustrate, riusciamo ad ottenere un menu sempre centrato orizzontalmente nella pagina, senza utilizzare hack CSS, dalla resa pressochè perfetta su tutti i browser più diffusi (Firefox, Opera, Safari, Internet Explorer 6, 7 ed 8), con un codice XHTML valido e semantico. Avendo utilizzato delle unità di misura in em o in unità percentuali, il menu supera brillantemente la prova del ridimensionamento del testo, salvaguardando da un lato l'integrità del layout della pagina e dall'altro l'accessibilità, una problematica da cui ormai non possiamo più prescindere. Prerogativa essenziale di entrambe le versioni è la semplicità del codice e dello stesso utilizzo.
Naturalmente, esiste anche il rovescio della medaglia. Un menu a tab grafiche con angoli arrotondati può risultare più attraente; alcune volte in ragione dei risultati estetici può essere necessario sacrificare l'uso di un hack, non sarà certo la fine del mondo. Inoltre, talvolta potrebbe risultare poco agevole l'eventuale integrazione con sub-menu a tendina in Javascript: in questi casi è meglio evitare i posizionamenti relativi o in linea e preferire comunque per una soluzione con i float e non centrata.
Il codice CSS e gli esempi dell'articolo sono disponibili per il download.