Pillole CSS: che cos’è il box model e come sfruttarlo per i nostri layout?

Negli ultimi due articoli abbiamo visto come strutturare un layout fisso a due e tre colonne utilizzando i float opposti, e abbiamo costruito una piccola pagina di esempio. Il risultato era accettabile, ma risultava un po’ troppo “attaccato”: ogni elemento era confinante con l’altro, appesantendo il tutto.

Proviamo a rendere più presentabile il layout sfruttando il box model.

Come già accennato nella conclusione dello scorso articolo, il problema del nostro layout era che gli elementi spaziavano per tutta la larghezza del contenitore, dato che avevamo impostato solo le width. Questo è il markup di riferimento:

<body>
...
<div id="contenitore-ricetta">
	<div id="ricetta">
		<h2>Ciambellone bigusto</h2>
		...
	</div>
	<div id="ingredienti">
		<h2>Ingredienti</h2>
		...
	</div>
</div> <!-- fine ricetta esterno -->
<div id="ricette_simili">
	<h2>Ricette simili</h2>
	...
</div>
...
</body>

A cui erano applicate le seguenti regole CSS:

body {
	...
	width: 1000px;
}

#ricette_simili {
	...
	width: 200px;
}

#ricetta {
	...
	width:600px;
}

#ingredienti {
	...
	width:200px;
}

Aggiungendo degli sfondi agli elementi, il problema è molto più evidente: come vedi non c’è nessun canaletto tra le varie colonne (che tra l’altro non si estendono nemmeno per tutta la lunghezza del layout). Una possibile soluzione è impostare i margini destro e sinistro all’elemento centrale, in questo modo:

#ricetta {
	...
	margin-left: 30px;
	margin-right: 30px;
	width:600px;
}

Andando a vedere il risultato non troviamo esattamente l’effetto sperato: l’elemento centrale si è spostato a sinistra, costringendo la colonna di sinistra a spostarsi in basso. Perché è successo questo? La chiave per rispondere a questa domanda è la comprensione del box model.

Le basi del box model

Fondamentalmente per i CSS esistono due tipi di elementi: gli elementi inline e gli elementi di blocco (Nota: esistono anche altri tipi, però sono molto meno utilizzati).

Grossolanamente parlando, gli elementi di blocco sono quelli che generano una nuova riga prima e dopo nel flusso del documento, occupandone tutta la larghezza. Un esempio di elementi di blocco sono i div, i paragrafi, i titoli (h1, h2, ecc.). Gli elementi inline invece sono quelli che stanno su una riga, all’interno di un testo. Ad esempio il tag span, oppure strong sono elementi inline. In questo articolo ci occuperemo degli elementi di blocco.

Come suggerisce il nome, tali elementi creano un riquadro nel documento. I componenti di tale riquadro, oltre alla width, sono margini, padding e bordi. Lo schema di un generico elemento di blocco potrebbe essere il seguente:

Esaminiamo questi elementi uno per volta:

  • Larghezza: rappresenta l’ampiezza dell’area in cui è posto il contenuto dell’elemento.
  • Padding: a volte chiamato “margine interno” è la distanza del contenuto dal bordo interno.
  • Bordo: è il bordo dell’elemento.
  • Margine: è uno spazio (trasparente) che circonda il blocco, impedendo agli altri elementi sovrapporsi ad esso.

Immaginando il blocco come un pacco, la larghezza è rappresentata dalle dimensioni del contenuto, il padding dall’imballaggio interno al pacco, il bordo è rappresentato dai limiti della scatola, mentre il margine è lo spazio che lo separa dagli altri pacchi.

La cosa fondamentale da capire riguardo al box model è che la larghezza di un elemento è data dalla width più il valore dei margini, del padding e dei bordi. Ovvero, se io imposto la width di un elemento a 100 pixel, e i margini destro e sinistro a 10 px ognuno, l’elemento risulterà largo complessivamente 120 pixel. Questo comportamento è un po’ controintuitivo: se io ho impostato una larghezza ad un elemento vorrei che fosse quella, nonostante margini o bordi. Purtroppo è questo il comportamento deciso dal W3C e a noi non resta che adeguarci.

Per fissare le idee dunque, un riquadro orizzontale è calcolato in questo modo: margine sinistro + bordo sinistro + padding sinistro + larghezza + padding destro + bordo destro + margine destro.

Modifichiamo il nostro esempio

Avrai quindi capito che il problema nel nostro esempio precedente era dovuto al fatto che l’elemento centrale aveva assunto una larghezza di 30 + 600 + 30 = 660pixel. Dato che la larghezza del contenitore è di 1000 pixel, i tre elementi sforano tale ampiezza, risultando in un layout sballato. Come risolvere questo problema?

La soluzione è molto semplice, anche se coinvolge alcuni calcoli matematici: in pratica bisogna sottrarre dall’ampiezza voluta dell’elemento, la somma delle ampiezze di margini, bordi e padding. Nel nostro esempio, avendo impostato solo i margini destro e sinistro a 30 pixel, dobbiamo effettuare la sottrazione 600 – (30 + 30) = 540 pixel. Questa sarà la width da impostare per l’elemento centrale, in questo modo:

#ricetta {
	...
	margin-left: 30px;
	margin-right: 30px;
	width:540px;
}

E come puoi vedere nell’esempio, ora tutti gli elementi sono rimasti al loro posto. Se avessi voluto aggiungere 20 pixel di padding ad entrambi i lati, ed un bordo di 1 pixel, la sottrazione sarebbe stata 600 – (30 + 1 + 20 + 20 + 1 + 30) = 518 pixel, e avrei ottenuto questo risultato

Il marginator

Per esperienza personale, so che spesso l’introduzione di formule matematiche non è bene accetta, dunque ho realizzato questo piccolo script (con l’aiuto di jQuery): il Marginator. Il Marginator permette di ricavare la larghezza da impostare ad un elemento nel modo più intuitivo possibile: si imposta la larghezza dell’elemento, gli eventuali margini, padding o bordi, ed il risultato sarà la larghezza da associare alla proprietà width dell’elemento.

Tag: , ,

L'autore

Appassionato di web design, si diletta a creare dei layout (X)HTML+CSS. È un maniaco del codice pulito e ordinato, il tipo di persona che vi ritrovate in casa a raddrizzarvi i quadri appesi alla parete. Ha deciso che diventerà un web designer con la “doppia vvu” maiuscola, e trascorre intere nottate sveglio per realizzare il suo sogno.

Sito web dell'autore | Altri articoli scritti da

Articoli correlati

Potresti essere interessato anche ai seguenti articoli:

16 commenti

Trackback e pingback

Non ci sono trackback e pingback disponibili per questo articolo