Galleria CSS

28 maggio 2008 css

La realizzazione di una galleria immagini pone sempre un problema: come presentare le miniature (o thumbnails). Se non ci fosse bisogno delle didascalie sarebbe tutto molto semplice: inserire una sequenza di tag img e lavorare un po’ con gli stili per renderla gradevole. Per inserire la didascalia sotto a ogni miniatura bisogna racchiudere i due elementi (miniatura e didascalia) all’interno di un box e poi gestire questo box. La soluzione di solito usata è di impostare per il box la proprietà float: left.

Cosa c’è che non va con “float: left”

Le gallerie fatte con float: left possono andare bene in molti casi, ma soffrono di alcuni difetti che fanno rimpiangere le tabelle:

  • non possono essere centrate nella pagina;
  • nei layout liquidi è facile creare spazi vuoti quando si ridimensiona la finestra;
  • i box devono essere della stessa altezza, pena l’andamento a scaletta dato dal float, e questo vuol dire poca flessibilità per la lunghezza delle didascalie.

L’ideale sarebbe poter avere un elemento con le stesse caratteristiche del tag img, ovvero poter essere trattato come testo (centratura nel contenitore, allineamento verticale rispetto alla linea base) ma avere caratteristiche da blocco (fungere da contenitore per altri elementi). La proprietà CSS per creare questo elemento esiste ed è display: inline-block.

Caratteristiche di “inline-block”

La proprietà display fa parte del Visual formatting model nelle specifiche W3C per il CSS 2.1. Permette di fare ciò che il suo nome suggerisce: costruire un elemento che si comporta all’interno come un blocco (un div) e all’esterno come un elemento inline (testo, span). Per lo scopo di una galleria sembra essere la soluzione a tutti i problemi. Sembra…

Diversità dei browser

Per quanto possa sembrare semplice, inline-block viene trattato in maniera diversa dai vari browser, e alcuni neanche la conoscono (vedi Quirksmode: The display declaration). Per impostare il comportamento del box in maniera consistente bisogna ricorrere a diverse dichiarazioni:

  • per i browser intelligenti
  • per Gecko (Firefox e compagni)
  • per Internet Explorer

Un esempio reale

Layout

Schema elemento galleria

Nell’esempio verrà costruita una galleria che avrà le seguenti caratteristiche:

  • layout fluido
  • l’intera galleria sarà centrata nel suo contenitore
  • didascalie di qualsiasi lunghezza

Ogni singolo elemento della galleria è stato impostato secondo questo schema (vedi figura):

  • miniature con dimensione massima 100px
  • contenitore della miniatura (classe .thumb) 140 × 140px
  • margine di 5px al div (classe .box) che contiene miniatura e didascalia

Da notare che la miniatura sarà centrata sia orizzontalmente che verticalmente all’interno del .thumb in modo da fornire un aspetto gradevole in caso di presenza di immagini sviluppate sia in orizzontale che in verticale.

Il codice HTML per ogni singolo box è molto semplice:

<div class="box">
  <div class="thumb"><span></span><img src="thumbnails/04310090.jpg" width="77" height="100" alt="La dama con l'ermellino" /></div>
  <div class="caption">La dama con l'ermellino</div>
</div>

Si nota subito la presenza di un elemento span vuoto. Questo è la base per un hack di Internet Explorer. Ci servirà più avanti per centrare verticalmente la miniatura all’interno del blocco .thumb.

Dopo aver letto (e cercato di capire) per qualche giorno, la soluzione è arrivata. Di seguito sono riportati e spiegati gli stili utilizzati. Per chiarezza e brevità ho rimosso dal codice tutte le istruzioni prettamente estetiche come bordi e sfondi, lasciando solo le istruzioni utili per il layout.

La classe “.box”

.box {
  display: inline-block;
  display: -moz-inline-box;
  -moz-box-orient: vertical;
  width: 140px;
  margin: 5px;
  vertical-align: top;
}

Per Internet Explorer dovremo aggiungere anche:

.box {display: inline;}

display: inline-block serve per tutti i browser che si comportano nella maniera giusta (come Opera), mentre per i browser basati su Gecko (come Firefox) bisogna inserire due istruzioni un po’ :esotiche: display: -moz-inline-box e -moz-box-orient: vertical. C’è di buono che queste ultime due sono delle istruzioni proprietarie del motore di rendering Gecko e quindi saranno completamente ignorate dagli altri browser. Come sempre, per Internet Explorer (almeno fino alla versione 7) bisogna fornire il codice display: inline separatamente tramite i commenti condizionali. Senza questo codice IE si ostinerà a trattare .thumb come un semplice blocco.

width: 140px e margin: 5px sono le specifiche imposte a piacere dal designer (cioè io). Possono ovviamente essere variate a seconda delle proprie esigenze badando solo ad impostare una larghezza che possa contenere le immagini delle miniature.

vertical-align: top serve per Opera. Senza questa regola, in caso di didascalie di lunghezza differente, Opera allinea i box al margine inferiore della didascalia, rovinando il layout (vedi immagine seguente). Il bello è che questo accade anche forzando le dimensioni verticali di tutti gli elementi e impostando overflow: hidden alla classe .caption!

Opera bug

La classe “.thumb”

.thumb {
  width: 140px;
  height: 140px;
  display: table-cell;
  vertical-align: middle;
  border: 1px solid #aaa;
}
.thumb * {
  vertical-align: middle; 
}

Per .thumb (che conterrà l’immagine della miniatura) si deve impostare anche l’altezza (io ho scelto di farla quadrata), dato che dovremo centrare verticalmente l’immagine al suo interno. L’allineamento verticale è sempre stato problematico con i CSS, almeno in confronto alla facilità con cui si ottiene nelle tabelle. La proprietà display: table-cell fa in modo che il box si comporti proprio come la cella di una tabella, mettendoci a disposizione vertical-align: middle che è l’equivalente di valign="middle" nelle tabelle.

vertical-align: middle applicato a .thumb * è un piccolo hack per Internet Explorer che altrimenti allinea le miniature al margine inferiore.

Sempre per Internet Explorer è necessario fornire separatamente questi stili:

.thumb {display:block}
.thumb span {
  display: inline-block;
  height: 100%;
  width: 1px;
}

IE non comprende bene display: table-cell e si rifiuta di applicare l’allineamento verticale con vertical-align: middle. Per forzarlo è necessario dichiarare .thumb come block e applicare le rimanenti regole all’elemento span vuoto che dovremo inserire all’interno del codice HTML, subito prima dell’immagine miniatura.

La classe “.caption”

Non c’è molto da dire per questa classe. In realtà potrebbe anche non essere usata e lasciare fluire la didascalia che rimane comunque all’interno di .box, ma può essere utile per applicare degli stili al testo della didascalia. Il div usato nell’esempio potrebbe anche essere sostitutito da un p.

Demo

L’esempio descritto è visibile nelle galleria demo. L’impaginazione è stata lasciata fluida (la situazione più difficile) per verificarne il comportamento quando si ridimensiona la finestra del browser. Sono presenti alcune didascalie molto lunghe per evidenziare come l’effetto scaletta che affligge i float non sia presente.

Compatibilità

Questa soluzione è stata verificata su un sistema Windows con i seguenti browser;

  • Internet Explorer 5.5
  • Internet Explorer 6
  • Internet Explorer 7
  • Opera 9.27
  • Firefox 2.0.0.12 (Gecko 1.8.1.12)
  • K-Meleon 1.5.0beta (Gecko 1.8.1.14)
  • Safari 3.1.2 (WebKit)

Tramite il servizio messo a disposizione da Browsrcamp ho testato la resa anche per Safari su Apple Mac OS X. Nella figura è riportato lo screenshot della pagina demo preso a 800px: sembra ok.

Riferimenti

Come sempre, Google è tuo amico, ma mi preme segnalare la grande risorsa CSS tests and experiments di Bruno Fassino, sia per la quantità che per la qualità del materiale pubblicato.

Commenti

13/05/2010 15:09 - augusto

...fantastico... mi hai risolto il problema in due min!!!!!! evvai con l'aumento dal BOSS!!!!

13/05/2010 16:24 - augusto

forse ho parlato troppo presto. Su Explorer non va, non c’ e’nulla da fare neanche con le soluzioni che tu hai postato!!!!! mi visualizza tutto su una unica colonna centrale. Su firefox tutto ok!!!

SOLUZIONI???????

grazie