Il box-model

Il box model di default, utilizzato nei css (versione 2) solitamente funziona così:

width + padding + border = larghezza visibile del nostro box
height + padding + border = altezza visibile del nostro box

La somma di questi parametri determina quindi quello che noi vediamo visivamente come box, da un’estremità all’altra.

Sembra strano come ragionamento, ma ci si abitua in fretta.

Il box-model di Internet Explorer 6 in modalità quirks

Purtroppo, Internet Explorer 6 ed i suoi predecessori utilizzano un box model (quando sono in modalità “quirks”) differente, che utilizza uno schema di ragionamento differente. E questo è forse la peculiarità più insopportabile con ogni webdesigner dei tempi di oggi si trova ad aver a che fare. Il box-model di IE6 infatti funziona così:

width = larghezza visibile del nostro box
height = altezza visibile del nostro box

Bordi e padding vengono considerati quindi “interni”, come elementi che tagliano, riducono la larghezza/altezza complessiva del box piuttosto che aumentarla. Nell’immagine seguente vediamo un esempio drammatico della differenza tra i due modelli:

Per chi ancora non avesse capito perchè IE6 viene tanto massacrato dai webdesigner, ora il concetto dovrebbe apparire più chiaro. A mio modo di vedere però, lo standard w3c, non è intuitivo, mentre la scelta fatta al tempo da microsoft lo era. Che cosa ci importa infatti di un parametro che definisca la larghezza solo del contenuto quando visivamente abbiamo un box che va da bordo a bordo? Tuttavia la scelta è stata fatta e ad IE6 questa volta va solo il torto di aver avuto un’intuizione, una proposta differente da quella che oggi è lo standard.

Abbiamo parlato però di “modalità quirks” (capriccio in italiano). Questa diversa interpretazione può essere “risolta” cambiando la dichiarazione doctype, secondo questo schema tratto da “Listamatic“, in modo da ritrovarsi nella modalità standard e non quirks:

Doctype utilizzatoWin/IE5Win/IE6Mac/IE5
HTML 4.01 Transitional – missing doctypeQuirksQuirksQuirks
HTML 4.01 Transitional – missing URL from doctypeQuirksQuirksQuirks
HTML 4.01 Transitional – full doctypeStandardsStandardsStandards
XHTML 1.0 Transitional – missing doctypeQuirksQuirksQuirks
XHTML 1.0 Transitional – missing URL from doctypeQuirksQuirksStandards
XHTML 1.0 Transitional – full doctypeQuirksQuirksStandards
XHTML 1.0 Transitional – missing PrologStandardsStandardsStandards
XHTML 1.0 Transitional – missing Prolog and URLStandardsStandardsStandards

L’argomento risulta tuttavia piuttosto complicato, e non è in questa sede che ci occuperemo di approfondirlo. Per chi fosse interessato potete approfondire ai seguenti links:

Io, personalmente, oltre a cercare di mandare in pensione IE6 appena ce n’è la possibilità, tendo a risolvere con gli hacks direttamente sul codice.

Il problema dei div discendenti con il box model w3c: un rompicapo!

Il rompicapo continua nelle implementazioni moderne. Immaginate di avere infatti un  <div> nella pagina contenuto dentro ad un div parente con una width di 500px. il div discendente avrà automaticamente una width (non parlo di larghezza perchè, nell’accezione a cui siamo abituati, la larghezza è intesa da un’estremità all’altra di un elemento) impostata al 100% larga quindi come il div parente (500px), senza che vi sia alcuna specifica definita.

Questo è il funzionamento degli elementi di blocco a livelli. Ma ora immaginiamo di aggiungere 10px di padding intorno al nostro div discendente ed un bordo di 2px. Che cosa accade? Il div discendente si comporterà in modo capriccioso, padding e bordi verranno infatti tagliati dall’interno del box. La larghezza visibile sarà quindi sempre di 500px. Ma che cosa succede se impostiamo la width del div al 100% in modo esplicito nel css? Il div discendente romperà il div parente perchè, secondo la logica del box-model, i 500px ereditati corrisponderanno alla width e non alla larghezza visibile del contenitore la quale risulterà quindi di 500px+10(x2)px+2(x2)px=524px.

Se vorrete assicurarvi che il box interno baci perfettamente i confini del div parente sarà necessario settare la larghezza del div discendente a 476px (500-24). Ma così facendo cadremo in un problema che, come si può facilmente intuire, complica la vita dei layout fluidi. Immaginiamo infatti che il div parente, invece di 500px, avesse una width settata al 72%. Come potremmo fare a fare in modo che un div discendente coincida perfettamente con questa dimensione? Il box model attuale non fornisce risposte. Le percentuali non è bene che vengano mischiate ai valori in pixel. Settando la width del div interno a 95.2% si otterrà il risultato voluto ma solo nel caso in cui il div parente sia visivamente largo esattamente 500px. Si tratta quindi di pura follia!

Abbiamo visto come, attraverso i <div>, i problemi siano molti e la risposta più immediata è quella di non usare mai la dichiarazione width:100%. Rimuovendo infatti questa proprietà risolveremo il nostro problema.  Tuttavia, c’è un altro elemento importante che necessità di poter settare questa dichiarazione e si tratta della <textarea>. All’elemento <textarea> infatti, non importa se lo dichiari come elemento di blocco, la sua width sarà determinata dal numero di cols dichiarate, a meno che non venga esplicitamente dichiarata. In un layout fluido, è bene che anche la textarea abbia una dimensione fluida combaciando correttamente a destra e a sinistra. Per fare ciò vorremmo poter usare una larghezza del 100% con bordi e padding definiti in pixel. E questa combinazione non è possibile.

La proprietà CSS3 Box-Sizing

La risposta a tutti i nostri problemi, giace nascosta in ciò di cui abbiamo parlato finora: il box-model. Per forzare i contenuti ad utilizzare il box model che vogliamo dobbiamo servirci della proprietà box-sizing in questo modo:

elemento {          -webkit-box-sizing: border-box; /* Safari/Chrome, other WebKit */          -moz-box-sizing: border-box;    /* Firefox, Gecko */          box-sizing: border-box;         /* Opera/IE 8+ */  }

La proprietà CSS3 box-sizing fa esattamente questo. Il valore border-box (al contrario del valore di default content-box ) rende il bordo l’elemento ultimo del nostro box e fa sì che la larghezza consideri padding e bordi come interni. Potremo così dichiarare finalmente gli elementi (e la nostra textarea) con una width del 100% senza incorrere in problemi per i contenitori discendenti.

Note

  • Gli unici browser “problematici” saranno IE7 ed i suoi predecessori che lavorano in modalità standard. Per fortuna potete sempre creare fogli stile specifici per questi browser!
  • Il prefisso moz supporta anche il valore padding-box che spinge il padding dentro il box ma non i bordo.
  • Funziona anche con le proprietà min-height, min-width, max-height, max-width.