Uno dei miei primi articoli su PRO, che risale a circa due anni fa, è quello sul box model. Ho pensato di proporre su questo blog un post su una delle tecniche che non è presente in quell’articolo, una tecnica di facile applicazione, solida, robusta e a prova di futuro.

Rivediamo brevemente il problema: se assegniamo una larghezza esplicita a un elemento, secondo le specifiche CSS questo valore indicherà l’area utile al contenuto, bordi e padding esclusi. Internet Explorer 5.0, 5.5 (e la versione 6 in quirk mode, ovvero senza un corretto doctype), interpreteranno tale valore come
la larghezza totale dell’elemento, includendo erroneamente, quindi, bordi e padding. Per ottenere un dimensionamento consistente le possibili soluzioni sono due:

  • Evitare di specificare la larghezza effettiva all’elemento e insieme bordi e/o padding
  • Usare uno delle tante versioni del box model hack

La prima soluzione è adottabile in casi semplici, ma il più delle volte tende a complicare le cose:
infatti per ogni elemento figlio diretto del contenitore a larghezza specifica dovremo indicare padding
e/o bordi orizzontali.

Ora vediamo come costruire la soluzione con il box model hack. Molte delle versioni dell’hack sono semplicemente inspiegabili da un punto di vista logico, e difficili da ricordare. La versione che vedremo qui è a mio parere la più logica e semplice.

Normalmente tra due dichiarazioni in cui sono in gioco la stessa proprietà, a prevalere è l’ultima. Vediamo un piccolo esempio:


p{
color: blue;
color: green}

Quale sarà il colore del testo dei paragrafi? Sarà verde in tutti i browser dato che il colore
verde viene specificato come ultimo in ordine di codice. Ora, la parola chiave !important è in grado di dare una maggiore priorità ad una dichiarazione. La seguente regola:


p{
color: blue !important;
color: green}

darà un testo blu in tutti i browser aderenti alle specifiche CSS2. Internet Explorer, versione 6 inclusa, non dà la priorità alla keyword !important, facendo si che il testo sia verde.
Ora spostiamoci sulle dimensioni. Vogliamo ottenere un elemento con larghezza totale di 200 pixel e larghezza effettiva di 180px, con 10px di padding sui lati.


div#box{
width: 180px !important;
width: 200px;
padding: 0 10px}

Nei browser recenti (Opera, Mozilla, Firefox e Safari) che interpretano correttamente il box model
e la keyword !important abbiamo ottenuto il dimensionamento voluto. Per Internet Explorer 5.x ci siamo: viene servita una larghezza totale di 200px.

Abbiamo ancora un problema: IE6 aderisce alle specifiche CSS per le dimesioni, e così abbiamo risolto
il problema su IE5.x per spostarlo su IE6. Questo browser infatti vedrà i 200px come larghezza
utile al contenuto, e otterremo quindi un box con 220px di larghezza totale.

Per sistemare le cose, basta un commento vuoto (prima dei due punti, e anticipato da uno spazio) per nascondere la seconda dichiarazione a IE6, che verrà comunque interpretata da IE5.x. Vediamo così la versione definitiva:


div#box{
width: 180px !important;
width /**/: 200px;
padding: 0 10px}

Abbiamo così ottenuto un dimensionamento consistente in tutti i browser in sole due dichiarazioni. C’è una cosa da notare: la tecnica di per sè non è un vero un proprio hack. Diciamo che è un hack parziale, solo per IE 5x, che non aderisce alla specifiche riguardo la parola chiave !important, e per IE6 che non legge il valore dopo il commento vuoto. Dietro comunque c’è una logica a sostenerla, che funziona nei browser attuali e dovrebbe garantirci che i browser futuri interpreteranno correttamente.

La tecnica ci consente di usare il box model hack anche nei rari casi in cui vorremmo stabilire un’altezza specifica, ecco l’esempio di un div con bordi e padding:


div#box{
height: 180px !important;
height /**/: 200px;
border: 5px solid #CCC;
padding: 5px}

Volendo si possono impostatare anche altezza e larghezza nella stessa regola.

Un’altra applicazione utilissima potrebb essere per la creazione di dichiarazioni specifiche per IE e per gli altri browser. Per esempio, dato che IE fino alla versione 6 non supporta le PNG trasparenti, potremo servigli una GIF. In questo caso il commento vuoto viene omesso, dato che vogliamo che la gif venga servita anche a IE6:


div#box{
background: url(shadow.png) !important;
background: url(shadow.gif)
}

Lo stesso approccio può essere usato per risolvere alcuni bug di IE, e in particolare il Peekaboo bug, ottenendo una versione un po’ più pulita dell’Holly Hack:


div#box{
height: auto !important;
height: 1%}

Questo è tutto Due approfondimenti in merito sono la serie di tre articoli sulla risoluzione dei problemi nella sezione CSS di PRO (primo, secondo
e terzo) e il mio articolo
in inglese CSS design for the future.

Share and Enjoy

  • Facebook
  • Twitter
  • Delicious
  • LinkedIn
  • StumbleUpon
  • Add to favorites
  • Email
  • RSS
16 CommentiDi' la tua

Il tuo indirizzo email non sarà mostrato pubblicamente. I campi obbligatori sono contrassegnati da *

La mia lettura é tardiva, ma penso non sia mai troppo tardi per fare i complimenti. :) Sono un programmatore embedded che per hobby si sta avvicinando all'web development, e ho trovato di chiarezza estrema questa soluzione a quello che é uno dei "barré" del web design. Grazie e... al prossimo articolo. ;)

Roberto Caboni
Roberto Caboni

Beh, é una tecnica utilissima! Risolve di certo una grandissima parte di problemi riguardanti i bug di IE...veramente fantastico. Ne ho sesntito spesso parlare di questi hack, ma non sapevo come utilizzarli e a cosa servissero veramente. Articolo illuminante!:-)

Simone
Simone

Nietta, il punto é che IE7 aderisce alle specifiche in merito a !important, quindi quello che succede in realtà  é il comportamento atteso. Potrebbe esserti utile una lettura all'articolo Hack per IE7 e la relativa Tabella di compatibilità .

Alessandro Fulciniti
Alessandro Fulciniti

Ciao! Anch'io uso sempre il hack "!important". Ho notato però che in un caso con IE7 non funziona: nel float. All'interno di una complicata struttura ho due blocchi che voglio avere l'uno accanto all'altro e devo specificare float:left; per Explorer e float:none; per Mozilla. Quindi scrivo: float:none !important; float:left; Ebbene IE7 considera più importante il float:none, fregandosene della riga successiva. C'é un workaround anche per questo problema? Grazie Nietta

Nietta
Nietta

Grab, ho usato il condizionale.. ma a parer mio non fa differenza che "width /**/: 200px;" venga letto da IE8 o no, dato che IE7 obbedisce alla keyword !important e prenderà  l'altra dichiarazione per buona. Se IE8 avrà  aderenza maggiore o uguale ai CSS di IE7, la tecnica non dovrebbe dar problemi.

Alessandro Fulciniti
Alessandro Fulciniti

Tecnica a prova di futuro? Qualcuno ha per caso idea di come si comporti "width /**/: 200px;" su internet explorer 8? Secondo me commenti condizionali sempre!!! Basta con workaround e hack.

Grab
Grab

Grazie mille per quest'articolo, era proprio quello che cercavo

Angelo
Angelo

Articolo utilissimo,grazie molto per il suggerimento!cercavo propio questo attributo "salva-visualizzazione".

federico
federico

Grazie Alessandro, concordo, ho avuto un po' di tempo in più per fare altre verifiche e non vale la pena di usare la mia proposta, molto meglio !important e /**/. Ho verficato inoltre che con IE per Mac (versione 5.2.3) non ha bisogno dell'hack, e supporta perfino le PNG con trasparenza. Certo IE per Mac ha altri difetti, ma sembra battere le versioni 5.x di Windows. Mi chiedo con che criterio quelli di Microsoft hanno realizzato IE 5 per le due piattaforme, sembrano quasi fatti da due team diversi... :-)

Maurizio Treppo
Maurizio Treppo

Maurizio, vedi.. ci sono due classi di hack: quelli che fanno leva sulle mancanze di supporto o aderenza dei CSS del browser da una parte e quelli che fanno leva sui rendering engines e i parser dall'altra. L'uso della keyword !important appartiene al primo tipo (a parte il commento vuoto che serve per IE6) e ci dovrebbe garantire che l'hack (o workaround che dir si voglia) funzionerà  anche in futuro. La soluzione da te proposta appartiene invece alla seconda classe, e soluzioni di questo tipo si rivelano a parer mio più instabili in quanto, mentre é auspicabile che i browser aderiscano alle specifiche CSS, non é prevedibile né sicuro di come possano reagire a sequenze di caratteri inaspettati e/o imprevisti nelle versioni a venire. Inoltre, non passa la validazione. In sostanza: un bel tentativo... ma non me ne volere, ne sconsiglierei l'uso.

Alessandro Fulciniti
Alessandro Fulciniti