Se avete seguito gli «articoli sui CSS» di HTML.it o se avete superato la fase di apprendistato avete certamente capito una cosa: i CSS sono uno strumento straordinario al servizio del web designer, ma la loro implementazione va incontro a grossi problemi. La radice di tutto ha un nome: incompatibilità. Tra browser diversi, tra versioni differenti dello stesso software, tra piattaforme.
L'attività di uno sviluppatore rischia così di trasformarsi in un'odissea, in una ricerca estenuante di trucchi e soluzioni alla miriade di bugs che affliggono i browser presenti sul mercato. Un'interessante esempio/discussione su quanto detto lo trovate sul sito usabile.it, recentemente "riscritto" aderendo agli standard del W3C. Anche qui il dilemma è stato: realizzare un sito standard-based o tenere conto anche dei browser più datati?
Una risposta valida sempre e per tutti non c'è. Se intendete usare i CSS mantenendo la compatibilità con il passato potete usare alcune tecniche definite e affinate negli anni. Ne prenderemo in considerazione tre:
- L'uso di un CSS universale
- Il metodo @import
- Lo sniffing dei browser con Javascript
Un CSS universale
La prima soluzione prevede la creazione di un foglio di stile che si adatti a tutti i browser (almeno a quelli che decidiamo di supportare completamente).
Vantaggi: risolviamo i problemi di incompatibilità. Punto. Lista degli svantaggi. Innanzitutto si dovrà necessariamente volare basso. Ovvero: scordiamoci le caratteristiche avanzate dei CSS. Secondo: bisogna armarsi di pazienza, tanta, e andare a verificare per ciascuna regola da definire le incompatibilità incrociate.
Se questa è la via che intendete percorrere non potete ignorare due risorse.
- La CSS Master List di Eric Meyer sul sito di WebReview: è una tabella in cui sono evidenziate tutte le proprietà di CSS1 e il modo in cui sono supportate dai vari browser (aggiornata il 14 gennaio).
- La Test suite di RichInStyle.com con l'annesso database dei bug: una batteria di test su tutti i bug di tutti i browser su tutti gli aspetti di CSS2. Praticamente la "Treccani" dei fogli di stile
Il metodo @import
Questo secondo metodo è certamente meno dispendioso in termini di tempo, diciamo più razionale. Si basa su un presupposto. C'è un browser che fa veri disastri con i CSS: il suo nome è Netscape 4. Se riusciamo a "ingannarlo" abbiamo risolto buona parte dei nostri problemi di compatibilità.
In effetti la soluzione poggia su una delle tante falle di Netscape: la sua incapacità di implementare il metodo @import. Vediamo di cosa si tratta.
Per collegare un foglio di stile ad una pagina si usa in genere il tag <link> all'interno della sezione <head>:
<link rel="stylesheet" type="text/css" href="stile.css" >
Esiste però un sistema alternativo, che prevede l'importazione di un foglio esterno all'interno dei tag <style> </style> tramite l'istruzione @import:
<style type="text/css">
@import url(stile.css);
</style>
La cosa per noi interessante è che le due modalità possono essere combinate nello stesso documento. In tal modo realizzeremo due fogli di stile. Il primo, specifico per Netscape 4, lo colleghiamo con <link>; il secondo, per gli altri browser, lo incorporiamo con il metodo @import. Per "altri browser" intendiamo quelli che offrono un supporto almeno decente di CSS1. Essi, operano una sorta di "fusione" tra i due fogli di stile, ma piazzando l'istruzione @import sotto il tag <link>, diamo ad essa più importanza e perciò i browser in questione privilegiano gli stili contenuti nel foglio così importato. Ecco come si presenta la sintassi:
<link rel="stylesheet" type="text/css" href="stile_netscape4.css" >
<style type="text/css">
@import url(stile.css); /*per IE 5, 5.5, 6 Win e Mac, Opera 5 e 6, Netscape6x */
</style>
Nell'esempio allegato potete osservare un'implementazione di questo metodo. Se avete Netscape 4 noterete subito le differenze.
Alcune importanti osservazioni per concludere.
- Attenzione alle regole che definite nei fogli di stile! Non mettete mai nel foglio per Netscape istruzioni che non usate nel secondo foglio. Mi spiego: se nel CSS per Netscape inserite, ad esempio, uno stile per il tag <h1> e non fate lo stesso nel secondo foglio, Explorer e gli altri browser, erediteranno quello stile. In pratica, se non trovano il selettore h1 nel primo CSS (@import) lo cercheranno nel secondo (<link>). Il risultato lo potete vedere nell'esempio allegato (punto 2).
- Potete invece fare il contrario: inserire nel secondo CSS classi o selettori in più rispetto al primo. Visto che Netscape ignora completamente l'istruzione @import, la cosa non produrrà effetti sgraditi (esempio, punto 3).
- Nel CSS per Netscape, visto il numero enorme di bug da cui è afflitto, vi consiglio di mantenervi sull'essenziale. Un utile articolo sui principali bug lo trovate sul sito del CSS Pointers Group.
- Il metodo @import funziona anche per Explorer 3 (ma esiste ancora?!).
Un CSS per ogni browser
L'ultimo metodo si basa sul classico sniffing del browser. Consiste essenzialmente nell'implementazione di un CSS specifico a seconda del software rilevato tramite poche linee di Javascript. L'argomento è stato trattato ampiamente e ottimamente in un precedente articolo di Html.it («Riconosciamo i browser con Javascript») al quale vi rimando per gli aspetti teorici e per il codice.
Vorrei solo fare al riguardo una piccola integrazione/osservazione. L'articolo spiega un semplice script che testa tre possibilità:
Condizione | Codice Javascipt |
---|---|
Se il browser è Netscape 4 carico il CSS x |
if (document.layers){ //Netscape 4.x |
Se il browser è Explorer (4, 5, 6) carico il CSS y |
else if (document.all){ // Explorer |
Se il browser è Netscape 6 carico il CSS z |
else if (document.getElementById){ //Netscape 6.x |
Come si può notare, lo script equipara le versioni di Explorer dalla 4 alla 6. Dal punto di vista del supporto dei CSS sarebbe però più corretto (e razionale) suddividere i browser diversamente. Explorer (Win o Mac) 5x e 6 sono da questo punto di vista molto più vicini a Netscape 6 che ad Explorer 4 (che ha un supporto piuttosto scarso). In pratica si tratta di rivedere lo script affinchè i browser con supporto del DOM implementino lo stesso CSS. Ecco una versione riveduta e corretta che svolge questa funzione:
<script language="JavaScript">
<!--
if (document.layers){ //Netscape 4.x
document.write("<link rel='stylesheet' href='stile_netscape4.css' type='text/css'>");
}
else if (document.all && !document.getElementById) { // solo Explorer 4
document.write("<link rel='stylesheet' href='stile_explorer4.css' type='text/css'>");
}
else if (document.getElementById){ //Netscape 6.x, Explorer 5 e 6, Opera 5 e 6, Mozilla
document.write("<link rel='stylesheet' href='stile_dom.css' type='text/css'>");
}
//-->
</script>
La parte in rosso è quella aggiunta. In questo modo tutti i browser che supportano l'espressione getElementById (quindi, anche se parzialmente, il DOM del W3C) caricheranno lo stesso CSS.
Lo stesso risultato (separare i browser di quinta generazione e aderenti agli standard da quelli più vecchi) si può ottenere anche in questo modo:
<script type="text/javascript" language="javascript">
<!-- //
if (!document.getElementById) {
document.write("<link rel='stylesheet' href='stile_vecchibrowser.css' type='text/css'>");
}
else {
document.write("<link rel='stylesheet' href='stile_dom.css' type='text/css'>");
}
// -->
</script>
Provate lo script in questo esempio. Caricatelo prima con un browser recente, poi (se lo avete) con uno datato.
I file usati negli esempi possono essere scaricati per una comoda visualizzazione offline. Alla prossima!