In questo articolo cercheremo di spiegare a fondo la teoria del box model.
Iniziamo con il dire che ogni elemento in una pagina html può avere margini,
bordi e padding. Ecco un esempio:
Mauris nulla. Nullam nec augue nec ipsum posuere ullamcorper.
Ut sit amet sem ac arcu iaculis pellentesque. Cras aliquet tristique libero.
Donec consectetuer orci dapibus eros. Nulla dapibus, tellus eu mollis mollis,
ligula risus venenatis tortor, vitae vestibulum odio elit eu quam. Proin rutrum.
Il box che stiamo considerando è quello con il bordo nero solido. La distanza
tra il suo bordo e il suo contenitore (con bordo tratteggiato) è il margin.
Il bordo nero solido è il border. Infine, la zona grigia che circonda il contenuto
(in giallo) è il padding.
Nota: dall' esempio si potrebbe intendere che ai margini,
bordi e padding si possa attribuire un colore. In realtà il colore si può assegnare
solo ai bordi e al contenuto. Altra cosa da considerare: i margini orizzontali
sono sempre trattati separatamente, mentre i margini verticali tra due elementi
adiacenti vengono collassati, cosa che molti non sanno. Consideriamo per esempio
il seguente codice html con stili in linea:
<div style="margin: 100px">Primo div</div>
<div style="margin: 50px">Secondo div</div>
Il primo div ha tutti i margini pari a 100px, mentre il secondo div ha margini di 50px.
Quale sarà la distanza verticale che li separa? Molti penseranno che sia 150 pixels.
In realtà la distanza che li separa è 100 pixels. Infatti la distanza verticale effettiva
tra due elementi con margini diversi da zero viene resa come il maggiore tra i due valori dei
margini verticali coinvolti.
Elementi inline ed elementi block-level
Molti non hanno chiara la differenza tra queste due categorie, ed è sovente
causa di errori di codifica di html e css. Cercherò di spiegarla al meglio.
Vediamo le differenze sostanziali:
- Un elemento block-level può contenere altri elementi block-level e anche
elementi inline, mentre un elemento inline può contenere solo altri elementi inline - Ad un elemento block-level si possono attribuire delle dimensioni.
- Ad un elemento inline, a meno che questo non venga dichiarato float,
posizionato o modificandone la sua natura con la proprietà display, non si possono
attribuire delle dimensioni (in realtà un elemento inline può avere solo una sorta di "dimensione verticale"
grazie alla proprietà line-height. La disposizione verticale di elementi inline con
la proprietà line-height impostata rispetto ad altri elementi inline adiacenti
e/o contenitori si controlla grazie alla proprietà vertical-align) - Elementi inline adiacenti vengono disposti orizzontalmente, mentre elementi block-level
vengono disposti verticalmente. - Un elemento block level di dimensioni non specificate occupa tra margini, bordi,
padding e contenuto, tutta la larghezza messa a disposizione del suo box contenitore.
In verticale occuperà l' altezza necessaria al suo contenuto. - Un elemento inline occuperà sia in orizzontale che in verticale l' altezza necessaria
al suo contenuto
Nel seguito dell' articolo verrà indicata una lista dettagliata di elementi inline ed elementi
block-level.
Box contenitori e box anonimi
In questo paragrafo vedremo come vengono resi elementi e testo all' interno dei contenitori (box).
Con il termine box si indicherà, se non specificato altrimenti, un contenitore generico,
tenuto conto che elementi block-level generano block box, mentre elementi inline
generano inline box.
Come già detto, elementi block-level possono contenere sia elementi block-level che
elementi inline, mentre gli elementi inline possono contenere solo altri elementi inline.
Vediamo un esempio con solo block box:
<div style="border: 1px dotted #000">
<div style="border-bottom: 2px solid #000" >Primo div</div>
<div style="background-color: #CCC">Secondo div</div>
</div>
In questo caso abbiamo due elementi block-level inseriti in un contenitore block level.
Vediamo come verranno resi:
Fin qui tutto semplice e chiaro. Anologamente, ecco due elementi inline
inseriti in un elemento inline:
<span>
<strong>Primo elemento</strong>
<em style="background-color: #FF0">Secondo elemento</em>
</span>
Ed ecco come verranno resi: Primo elemento Secondo elemento.
Si noti che non verranno separati verticalmente, ma continueranno orizzontalmente nel box padre e sulla
stessa riga di testo.
Ora vediamo due elementi inline inseriti in un elemento block-level:
<div style="border: 1px solid #000">
<strong>Primo elemento</strong> <em>Secondo elemento</em>
</div>
L' effetto del codice sopra è:
Ora, dopo questa prima parte introduttiva che alcuni lettori avranno potuto trovare noiosa,
arriviamo agli esempi chiave per comprendere i box anonimi. Un box anonimo in sostanza
è un box che viene generato per contere del testo. A seconda dei suoi "fratelli", cioè degli
altri elementi contenuti nel contenitore padre, la sua natura sarà di box anonimo inline o box anonimo
block-level. Vediamo un esempio di box anonimo inline:
<p>Sono un box anonimo inline.<strong>Elemento inline con box inline.</strong></p>
L'effetto com' è evidente, e che il testo verrà reso come box inline. Ecco il risultato:
Sono un box anonimo inline.Elemento inline con box inline.
Ci sono dei casi in cui una semplice porzione di testo viene reso come box anonimo block-level. Eccone uno:
<div style="border:1px solid #000">
<div style="background-color: #ccc">Primo elemento block-level</div>
Elemento di testo che verrà reso come box anonimo
<div style="background-color: #ccc">Secondo elemento block-level</div>
</div>
In questo caso il testo senza contenitore verrà reso racchiuso in un box anonimo block-level, proprio come se fosse contenuto in un div:
Elemento di testo che verrà reso come box anonimo
Non solo inline o block-level
Finora abbiamo parlato di elementi block-level e di elementi inline. Ma vi sono elementi particolari che non
rientrano nelle due categorie. Tra questi, i paragrafi che non possono contenere altri elementi
block-level, i form, tutti gli elementi relativi alle tabelle, le liste ordinate e non, i list-item e le liste di definizione.
Questi elementi, essendo capaci di avere delle dimensioni impostate, sono parenti stretti degli elementi block-level puri.
Curiosità: già che abbiamo parlato di box anonimi, sarà utile sapere che il numero delle liste
ordinate o il bullet (che di default è un disco nero) viene reso come elemento anonimo inline all'
esterno del list item, a meno che non si specifichi list-style-position: inside.
Il mio invito è, nel caso di dubbi sulla natura di un elemento e per evitare errori di scrittura del codice,
a consultare l' ottima reference dell' html 4.0
di htmlhelp che riporta per ogni tag la sua presentazione. Inoltre, i principali validatori html segnalano errori relativi a contenitori e errata inclusione
per esempio di elementi block-level all' interno di elementi inline. Questo è solo uno dei motivi importanti per cui bisognerebbe
sempre validare il codice HTML scritto. Ecco i due principali validatori html:
Elementi block-level, margini e padding
I vari browsers per consentire una visualizzazione dignitosa di una pagina html che non ha foglio di stile linkati,
attribuiscono valori di default per margini e padding ad alcuni elementi block-level e altri elementi. Tra questi
vi sono il body, le liste, i paragrafi e gli header. Per quanto ne so, solo i div e gli elementi inline hanno margini
e padding di default a zero dal browser. Per gli altri elementi, valori di margin e padding vengono "assegnati d' ufficio"
e non vi è modo di venirne a conoscenza con precisione. Infatti tali valori dipendono da molti fattori, tra i quali la risoluzione dello schermo, la dimensione dei font della pagina
e impostata tramite le opzioni del browser e soprattutto dai browsers stessi. Il pieno controllo di una pagina html con
i fogli di stile, se vogliamo che renda le spaziature uguali in tutti i browsers, implica lo specificare valori di
margini e padding per tutti gli elementi che verranno utilizzati e che hanno valori di default non nulli.
Elementi block-level e dimensioni
Come abbiamo già detto all' inizio dell' articolo, un elemento block-level di dimensioni non specificate occupa
tra margini, bordi, padding e contenuto, tutta la larghezza messa a disposizione del suo box contenitore.
In verticale occuperà l' altezza necessaria al suo contenuto. Cosa succede se io volessi specificare le sue dimensioni
tramite i fogli di stile? Le proprietà css 'height' e 'width' servono a questo scopo.
Nota: una trattazione esauriente sul dimensionamento degli elementi block-level attraverso tutte le
possibili unità di misura è al di fuori della portata di questo articolo,e da qui in poi si farà solo uso del dimensionamento
in pixel.
Il box model prevede che le dimensioni specificate via css di un block-level
element siano le dimensioni della sua area utile al contenuto. Vediamo subito l' esempio di un div con larghezza impostata a 200 pixel.
<div style="border: 5px solid #000; padding:10px; width: 200px; background-color: #ccc">
<div style="background-color: #ffc">Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
Mauris nulla. Nullam nec augue nec ipsum posuere ullamcorper. Ut sit amet sem ac arcu iaculis pellentesque.
</div>
</div>
Ed ecco come viene visualizzato:
Mauris nulla. Nullam nec augue nec ipsum posuere ullamcorper. Ut sit amet sem ac arcu iaculis pellentesque.
Come già detto, la larghezza dichiarata tramite la proprietà css 'width' del block-level element corrisponde all' area
utile al suo contenuto.
In questo caso quindi il rettangolo giallo con il testo se state visitando questa pagina con un browser standard-compilant
dovrebbe essere largo esattamente 200 pixel, e alto il giusto per contenere il div con il testo.
Il box model errato di IE5.x e il box model hack
Se state visualizzando questa pagina con Internet Explorer 5 o Internet Explorer 5.5 sicuramente il rettangolo
giallo dell' esempio sopra non sarà largo 200 pixel, ma esattamente 170 pixel. Questo perchè Internet Explorer include
erroneamente nelle dimensioni dichiarate bordi e padding. Negli altri browsers come Internet Explorer 6,
Opera e Mozilla il box giallo sarà giustamente largo 200 pixel.
Ora, lo scopo fondamentale dei css è curare la presentazione dei contenuti e, in teoria, di essere un standard per tutti
i browsers. Quando si realizza una pagina html e la si correda di un foglio di stile, quello che si vorrebbe è che la pagina
renda uguale su tutti i browsers. Nella realtà ci si scontra sempre con le diversità di interpretazione dei css sui vari browsers.
Ma in quanto al box model, si sono trovate diverse soluzioni per risolvere l' errata interpretazione di IE 5.x. Vi
elencherò le due più note:
Una trattazione esauriente dei box model hack richiederebbe non poche righe e esula dallo scopo di questo
articolo, vi rimando quindi agli articoli originali in lingua inglese. Ma ci tengo comunque a mostrarvi
come sia possibile specificare via css un box con css 'width' effettiva pari a 200 pixel su tutti i browsers.
La regola css in entrambi i casi non può essere specificata tramite uno stile in linea ma in un css incorporato
nella sezione head un css esterno, e specificato via html così:
<body>
<div id="box200">Duecento pixel reali di contenuto</div>
</body>
Box Model hack di Tantek:
div#box200{
border: 5px solid #000;
padding:10px;
width: 170px;
background-color: #ccc;
voice-family: ""}"";
voice-family:inherit;
width: 200px;
}
body>div#box200{
width: 200px
}
Simplified Box Model hack:
div#box200{
border: 5px solid #000;
padding:10px;
width: 170px;
background-color: #ccc;
}
div#box200{
width: 200px;
width: 170px;
}
Variante condensata del Simplified Box Model hack:
div#box200{
border: 5px solid #000;
padding:10px;
width: 170px; width: 200px; width: 170px;
background-color: #ccc;
}
La proprietà display
La proprietà display serve per controllare via css come (e se) un elemento viene reso dal browser.
Una trattazione approfondita
di questa proprietà si può trovare sulla Reference del W3C.
Il mio consiglio è di usare con parsimonia la proprietà display, soprattutto nel cambiare la natura visuale degli elementi
in una pagina html.I tre valori fondamentali che la proprietà display può assumere sono:
- display: none;
- Dichiarando un elemento 'display: none' stiamo dicendo al browser di non generare nessun box per il
suo contenuto. Quindi nè il testo nè tutti gli elementi contenuti all' interno verranno resi
visivamente, proprio come se non ci fossero nell' html. - display: block;
- In questo caso si forza un elemento a diventare block-level. Viene usato comunemente nei link
per creare 'link a tutto campo' in cui la regione cliccabile è l' intera area utile del contenitore block-level generato e non
solo il testo. - display: inline;
- Dichiarando in questo modo un elemento, questo viene reso in un contenitore inline.
Un uso comune e diffuso della proprietà display è dichiarare 'display: block' i link, cioè i collegamenti
ipertestuali delle pagine web espressi tramite il tag <a>. Questo consente di attribuire ad un elemento
per sua natura inline, una presentazione come block-level element, e quindi attribuire dimensioni ed estendere
l' area cliccabile del link all' intero box e non solo al testo.
La proprietà overflow
La proprietà overflow serve per definire il comportamento di un block-level element nel caso il suo contenuto ecceda dalle sue dimensioni
esplicite, ossia nel caso in cui l' area utile del block-level box non è sufficiente per i contenuti. I valori possibili per
la proprietà overflow sono:
- overflow: visible;
- autorizza il contenuto ad espandersi oltre il suo contenitore. E' il valore impostato di default.
- overflow: hidden;
- Si vieta al contenuto di oltrepassare il suo contenitore. In questo caso il contenuti
quindi verrà 'tagliato'. - overflow: scroll;
- Anche se il contenuto non eccede il contenitore, il contenitore avrà le barre di scorrimento.
- overflow: auto;
- Se necessario, il contenitore avrà una o tutte e due le barre di scorrimento.
Ecco un esempio:
<div style="width: 150px; height: 150px; overflow:auto;background-color: #ffc">
Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
Mauris nulla. Nullam nec augue nec ipsum posuere ullamcorper.
Ut sit amet sem ac arcu iaculis pellentesque. Cras aliquet tristique libero.
Donec consectetuer orci dapibus eros. Nulla dapibus, tellus eu mollis mollis,
ligula risus venenatis tortor, vitae vestibulum odio elit eu quam. Proin rutrum.
</div>
Ed ecco come viene reso:
consectetuer adipiscing elit. Mauris nulla. Nullam nec augue nec ipsum posuere ullamcorper.
Ut sit amet sem ac arcu iaculis pellentesque. Cras aliquet tristique libero. Donec consectetuer
orci dapibus eros. Nulla dapibus, tellus eu mollis mollis, ligula risus venenatis tortor, vitae
vestibulum odio elit eu quam. Proin rutrum.
Il float model.
Una trattazione dettagliata sul float model richiederebbe un articolo voluminoso almeno quanto
questo. Per le nozioni teoriche sul float, rimando al
paragrafo sul float della
Reference del W3C.
Ma dato che abbiamo parlato di box model, vorrei aprire una piccola nota. Gli elementi dichiarati float,
di qualsiasi natura essi siano possono avere margini, bordi e padding come tutti gli altri elementi.
E soprattutto, possono avere dimensioni esplicite. Questo perchè un elemento dichiarato float viene
reso automaticamente con la proprietà 'display:block'.
Due parole sulle dimensioni implicite degli elementi float. Un' elemento float, pur essendo un block-level
element a tutti gli effetti, se non dichiarato attraverso dimensioni esplicite, assumerà la dimensione
orizzontale massima per il suo contenuto, e quella verticale necessaria.Esempio:
<div style="border:1px solid #000">
<em style="float:left;line-height:50px;background-color: #ccc;font-size: 20px;">Lorem</em>
ipsum dolor sit amet,consectetuer adipiscing elit. Mauris nulla. Nullam nec augue nec ipsum posuere ullamcorper.
Ut sit amet sem ac arcu iaculis pellentesque.
Cras aliquet tristique libero. Donec consectetuer
orci dapibus eros. Nulla dapibus, tellus eu mollis mollis, ligula risus venenatis tortor, vitae
vestibulum odio elit eu quam. Proin rutrum.
</div>
Ecco il risultato:
ipsum dolor sit amet,consectetuer adipiscing elit. Mauris nulla. Nullam nec augue nec ipsum posuere ullamcorper.
Ut sit amet sem ac arcu iaculis pellentesque.Cras aliquet tristique libero. Donec consectetuer orci dapibus eros.
Nulla dapibus, tellus eu mollis mollis, ligula risus venenatis tortor, vitae vestibulum odio elit eu quam. Proin rutrum.
Il box model degli elementi posizionati
Una piccola parentesi anche sul box model degli elementi posizionati, in particolare dichiarati 'position: absolute'
o 'position:fixed'. Questi vengono automaticamente resi 'float:none' e 'display:block'. Il loro comportamento con
dimensioni implicite è come quello deglo elementi float. La differenza sostanzale rispetto agli elementi float è che
gli elementi posizionati assolutamente o fixed vengono rimossi dal flusso normale degli elementi nella pagina.
Nota: Internet Explorer 5.x e 6 non hanno supporto per 'position: fixed'.
Conclusioni e credits
Spero che quest' articolo sia risultato utile e gradevole a tutti i lettori. Ho cercato di mantenere l' attenzione
anche al lettore esperto di css, fornendo informazioni difficilmente reperibili se non su reference che a volte possono
risultare di difficile lettura per il loro elevato livello di dettaglio, per il fatto che sono in inglese e l' assenza
di esempi e nozioni orientate alla pratica.
I crediti dovuti per la stesura di questa pagina sono: