Alcuni metodi per servire un foglio di stile solo ad Opera browser: un’hack con i CSS, lo sniffing del browser con la libreria Javascript if-Operas.js o l’utilizzo di PHP.
Sommario:
- Introduzione.
- Una hack con i soli CSS: le Media Queries.
- Tecniche di sniffing.
- Riferimenti ed approfondimenti.
Introduzione.
Opera non è un browser molto diffuso, ma è probabilmente il browser maggiormente compatibile agli standard web. Per questo motivo, e per il fatto che anche Opera, comunque, i suoi bug di interpretazione dei CSS li ha, puÃ?² capitare che la visualizzazione delle pagine sia diversa in questo browser rispetto che ad altri.
Se riuscite a realizzare un layout ben visualizzato con Internet Explorer e con gli altri browser, ma che presenta qualche problemino con Opera, e se non riuscite proprio ad aggirare il problema, una possibile soluzione potrebbe essere l’utilizzo delle Media Queries CSS3, che permettono, attualmente, di definire regole leggibili esclusivamente ad Opere 7 e superiori.
Una hack con i soli CSS: le Media Queries.
Non mi soffermo molto su questo filtro, che è comunque documentato nellÃ?â??articolo Making CSS visible for Opera 7 only
di Arve Bersvendsen, mi limito a riportarne un esempio che ne dovrebbe chiarire l’uso:
@media all and (min-width: 0px){
/* Qui puoi inserire normali regole CSS
che saranno lette solo da Opera 7 e superiori */
}
LÃ?â??utilizzo di questa hack fa (farÃ? ) perÃ?² nascere altri problemi: molti browser supportano giÃ? in parte i CSS3 e presto potrebbero supportare anche lÃ?â??utilizzo delle Media Queries. Inoltre anche le future versioni di Opera continueranno a supportarle (salvo casi di involuzione). Quindi in futuro, regole definite per correggere un comportamento di Opera potrebbero creare problemi con tutti gli altri browser.
Una alternativa è l’utilizzo di tecniche di "sniffing", ovvero individuare se la pagina si sta visualizzando con Opera e, nel caso, fornire un foglio di stile appropriato.
Tecniche di sniffing.
Se si opta per questa soluzione, è importante conoscere la funzionalitÃ? di Opera, introdotta dalla versione 7, di mimetizzarsi, cioè spacciarsi per un altro browser.
Gli header HTTP User-Agent inviati da Opera, a seconda delle opzioni, dovrebbero presentarsi simili ai seguenti:
- Nel caso si identifichi come Internet Explorer:
Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; en) Opera 9.00- Nel caso si identifichi come Mozilla:
Mozilla/5.0 (Windows NT 5.1; U; en) Opera 9.00- Nel caso si identifichi come Opera:
Opera/9.00 (Windows NT 5.1; U; en)
Ora che sappiamo come Opera si identifica, vediamo come riconoscerla.
Sniffing con Javascript.
Dato che Opera non è un browser molto diffuso, dato che dei suoi utenti, in pochi navigheranno con Javascript disabilitato, e dato che, spero, il servire regole specifiche ad Opera, ci serve per correggere solo piccoli problemi di visualizzazione, una soluzione accettabile potrebbe essere quella di utilizzare Javascript per identificare il browser, senza scomodare la programmazione lato server.
Per lo sniffing di Opera utilizzando Javascript, vi propongo la piccola libreria di facile utilizzo if-Operas.js.
Il codice minimo da inserire nell’HEAD del documento è il seguente:
...
<head>
...
<script type="text/javascript" src="if-Operas.js"></script>
<script type="text/javascript">
if_opera(’opera.css’);
</script>
…
La funzione if_opera() verifica se il browser che si sta utilizzando è Opera, e, nel caso, include il foglio di stile opera.css.
Volendo, lo sniffing si pu�² affinare ulteriormente, includendo il foglio di stile solo per una versione, fino ad una versione o a partire da una versione di Opera.
In questo caso, al posto di if_opera('opera.css'), dovrete usare la seguente sintassi:
if(is_opera(versione,param)){
AddCss(’opera.css’)
}
Oltre all’indirizzo del foglio di stile, i parametri da personalizzare, entrambi opzionali, sono version, che identifica la versione di Opera da verificare, e param, che puÃ?² assumere uno dei seguenti valori:
- lt
- Che sta per Less-than, minore di.
- lte
- Less-than or equal, minore o uguale.
- gt
- Greater-than, maggiore di.
- gte
- Greater-than or equal, maggiore o uguale.
Ricordano vagamente i commenti condizionali di Internet Explorer, vero?
Vediamo qualche esempio di utilizzo:
// Per Opera 7 e superiori:
if(is_opera(7, ‘gte’)){
…
// Per le versioni di Opera inferiori alla 7:
if(is_opera(7, ‘lt’)){
…
// Per Opera 7.01, 7.03, ma non 7.11:
if(is_opera(7.0)){
// Importa il CSS opera.css
AddCss(’opera.css’)
}
// Esclude Opera:
if(!is_opera()){
AddCss(’not_opera.css’)
}
Il limite di questo metodo è che funziona solo se l’esecuzione degli script è abilitata.
Sniffing lato server con PHP.
Ricorrere ad uno sniffing lato server per servire un foglio di stile ad hoc forse è un po’ esagerato. Comunque, utilizzando PHP, Opera si potrebbe riconoscere utilizzando questo codice:
<?php
if(strstr($_SERVER['HTTP_USER_AGENT'],"Opera")){
preg_match("|Opera[/ ]*([0-9.]+)|", $_SERVER['HTTP_USER_AGENT'], $version);
echo "You are using Opera $version[1]";
}
?>
Il codice, se l’header HTTP User-Agent contiene la stringa “Opera”, cerca con una espressione regolare la relativa versione, che puÃ?² essere adiacente o alla stringa “Opera ” (con uno spazio prima della versione) o ad “Opera/”.
Il codice appena visto, come con lo sniffing in Javascript visto in precedenza, riconosce Opera a prescindere da come si identifichi (IE, Mozilla o Opera). Se un codice simile fosse utilizzato in un sistema di statistiche, sarebbe importante che precedesse il controllo di Mozilla ed Internet Explorer.
Quindi, se avessimo una struttura di controllo come questa:
if(MSIE)
elseif(Opera)
Il sistema non riconoscerebbe Opera nel caso in cui si identificasse come Internet Explorer, a differenza di una struttura come la seguente:
if(Opera)
elseif(MSIE)
Speriamo non ci si mettano anche gli altri browser a spacciarsi per qualcos’altro, anche se, di estensioni per Firefox e Mozilla che giÃ? lo fanno, penso ne esistano.
Riferimenti ed approfondimenti.
Sui fogli di stile:
- Some CSS related bugs in Opera 8.5, un elenco di alcuni bug di Opera 8.5.
- Media Queries CSS3, Il documento del W3C candidato a diventare raccomandazione.
- Making CSS visible for Opera 7 only, la documentazione di un’hack per rendere visibile regole CSS solo ad Opera 7 e superiori utilizzando le Media Queries.
Su Javascript:
- JavaScript Browser Sniffer, uno script molto completo per lo sniffing dei browser.
- Using the navigator object to detect client’s browser, un articolo sull’uso di Javascript per individuare browser e versione.
- Javascript e CSS: binomio perfetto, un articolo di Andrea Fulciniti su come applicare stili ai documenti utilizzando Javascript.
tag: browser, CSS, hack, Javascript, Opera, PHP, Sniffing.
post correlati:
- Diversi stili per diversi browser
- Il doctype switch
- Escape completo di una stringa ASCII con Javascript o PHP
- Forzare l'aggiornamento della cache per file esterni
- This Style (Plugin per WordPress)
- Tracciare link esterni e download con Google Analytics Asincrono
- Trovare la definizione di una funzione in PHP

18 June 2006 alle 18:41
Grazie mille per questa “dritta” con Opera. Il file javascript per lo sniffing è veramente utile e di una semplicitÃ? disarmante.
Ottimo Lavoro.
5 July 2007 alle 21:14
ho provato a sniffare in javascript ma non riesco a farlo funzionare.
sapete come aiutarmi?
20 January 2009 alle 14:05
Ciao :-)
Anni fa per realizzare un semplice script in PHP creai una libreria in PHP che faceva la stessa cosa della tua, la usavo per fare un po’ quello che hai proposto tu, poi mi resi conto di due cose, ovvero, che esistono i commenti condizionali, molto ma molto più comodi da usarsi di qualsivoglia script e soprattutto di cercare di evitare di usare tanti fogli di stile diversi per non perderci nel mare delle verifiche e debug :-)
In fondo il senso di inserire un foglio di stile esterno è quello di snellire sia la procedure di modifica delle pagine del sito che quella di evitare di dover far scaricare dal server inutilemente, sempre le stesse cose. Ma se ce ne metti troppi poi siamo da capo a dodici :-) troppi pezzetti, uguale manutenzione difficile e continuo lavorio tra server e client per ogni modifica.
Così in genere lo evito soprattutto per Opera che tutto sommato ha pochi e ben precisi hack, noto quello per i menù generati da una lista non ordinata: ul li {display: inline} messo dopo della definizione di ul li a {display: block} ad evitare che Opera inserisca uno spazio arbitrario tra i vari link.
Insomma per queste cosucce non vale la pena di realizzare un file a parte, cosa ovviamente differente tra i vari IE, lì c’è poco da fare a volte, ma almeno con i commenti condizionali si risolve bene.
M.
22 January 2009 alle 23:06
Ciao Marco, non ti nascondo di essere ormai un po’ arrugginito con i CSS, soprattutto per quanto riguarda Opera :-)
Sicuramente cercare di risolvere con qualche workaround direttamente nel CSS “ufficiale” è la soluzione migliore, e se ci si riesce… ottimo! Ad esempio il problema che citi per i link trasformati in elementi block e contenuti in un elenco puntato, non sapevo neanche che si verificasse in Opera… ma ho sempre utilizzato quello stesso workaround per risolvere quello stesso problema con IE.
Ma comunque, ripeto, risolvere con qualche workaround è l’ideale. Se però proprio non ci si riesce, dato che i commenti condizionali funzionano solo per IE su Windows (non con Opera), e dato che appunto Opera non è così diffuso, per “patchare” qualche problemino che si può risolvere con un paio di regole specifiche per Opera, per non perderci troppo tempo (che è denaro! :-P), una non troppo cattiva soluzione potrebbe essere:
- un hack con i CSS - che, ti faccio notare, è diversa concettualmente da un workaround (ma, essendo arrugginito sull’argomento, non garantisco che l’hack proposto in questo post del 2006 sia ancora funzionante senza creare problemi con altri browser, è proprio questa la pecca di utilizzare un hack)
- uno sniffing con Javascript
- uno sniffing lato server controllando lo Useragent e facendo attenzione alla caratteristica di Opera di spacciarsi per altri browser
1 February 2009 alle 16:02
Il problema dello sniffing è che devi essere arcisicuro che ciò che stai cercando sia esattamente ciò che troverai :-)
Mi spiego meglio: analizzando la stringa di risulta come ho fatto io e come hai fatto tu è molto pericoloso se il client tende a nascondersi e a cercare di fare cose che se fosse identificato correttamente non potrebbe fare.
Ad esempio le botnet sono un pericolo.
D’accordo poco importa se il nostro scopo è solo quello di fargli scegliere un foglio di stile piuttosto che un altro.
Quello che mi chiedo è ma conviene scrivere uno script fatto così per linkare un altro script che corregge poche cose che possono essere risolte in altro modo e più in fretta?
Io credo che debba essere valutato volta per volta.
Anche il tuo discorso hack sì o no, la questione è che comunque non puoi non aggiornare il tuo script all’uscita di ogni nuovo modello di browser, e allora che fai?
Ma intanto sapere esattamente cosa si sta facendo, per esempio il problema da te citato di IE ho scoperto che non è sempre vero, cioè, dipende dal sistema operativo del server.
Pazzesco ma è così e solo perché IE da buon prodotto Microsoft per andare a capo vuole due caratteri mentre Unix e Mac no, uno solo.
Quindi interpreta un accapo bene e l’altro come richiesta di riga nuova :-(
Per risolvere il problema il trucco è di scrivere tutta la lista di link su una sola riga, senza a capo, brutto ma funziona e risolve il problema. E tra mille anni quella pagina sarà ancora leggibile anche se userai IE2300 :-)
Non ci sono hack, non ci sono work arround, solo una maledetta riga lunga un chilometro.
M.
PS oggi tendo a “fregarmene” di hack, preferisco guardare avanti, non realizzare siti che si vedono solo a quella risoluzione o con quel browser ovvio che no, ma evitare di far vedere un sito ad any browser che però non mi permette di usare che so Ajax come tecnologia, è il caso dei vecchi Opera :-)
31 March 2009 alle 21:30
Ciao Marco, scusa il ritardo :P
Guarda, sono pienamente d’accordo con tutto quello che scrivi.
Però scrivere il codice su una riga per evitare un bug è un workaround :-)
Per questo dico che un workaround in linea di massima è più robusto…