Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

Javascript e CSS: binomio perfetto

Analisi dei metodi Javascript per interagire con i fogli di stile CSS
Analisi dei metodi Javascript per interagire con i fogli di stile CSS
Link copiato negli appunti

C'è una certa classe di soluzioni Javascript che si sposa benissimo con i fogli di stile. Ne conto diverse anche negli articoli che ho scritto, a cominciare dai Tooltip con Javascript e CSS, passando per i Un menu espandibile con Javascript e CSS, i Nifty corners, il sistema di presentazione Presentazioni con CSS e Javascript e infine i Bubble Tooltips, solo per citarne alcuni.

I possibili modi per far cooperare Javascript e CSS sono davvero molti, ne vedremo alcuni in questo articolo. Cominciamo subito.

Aggiungere stili CSS direttamente da Javascript

Una delle caratteristiche più utili di Javascript, e del DOM in particolare, la possibilità di aggiungere e modificare stili CSS degli elementi di pagina. I modi sostanzialmente sono tre. Il primo e più noto consente di aggiungere e/o modificare singole dichiarazioni CSS grazie alla proprietà style di ogni elemento DOM. Dopo il punto che individua l'elemento seguirà la parola chiave style seguita dal punto e dall'equivalente Javascript della proprietà CSS.

Per le proprietà CSS composte da una singola parola. l'equivalente Javascript la proprietà stessa, mentre per le proprietà separate da un trattino, questo sparirà e trasformerà in maiuscola la lettera successiva (per esempio border-width diventa borderWidth). Ecco un piccolo esempio, in cui all'elemento con id="bigtext" verrà attribuito un font-size di 50 pixels:

var el=document.getElementById("bigtext");
el.style.fontSize="50px";

Una menzione particolare va alla proprietà float, il cui equivalente Javascript non segue la regola vista prima essendo float una parola riservata in Js: gli equivalenti saranno quindi cssFloat per browser quali Opera, Mozilla e Safari, mentre styleFloat per Internet Explorer. Basterà impostarle entrambe per ottenere il risultato voluto in maniera cross-browser:

var el=document.getElementById("box");
el.style.styleFloat="left";
el.style.cssFloat="left";

Se le dichiarazioni CSS da aggiungere mediante Javascript dovessero essere diverse c'è un'alternativa che si rivela più leggera in termini di peso: intervenire sull'attributo HTML style degli elementi di pagina, proprio come se si impostasse uno stile in linea, attraverso il metodo setAttribute. Anche in questo caso c'è qualche diversità di approccio tra Internet Explorer e gli altri browser, ma c'è comunque un modo semplice di procedere. La seguente funzione, tratta da SlayerOffice, permette di applicare una stringa CSS come stile inline ad un elemento:

function so_applyStyleString(obj,str){
if(document.all && !window.opera)
    obj.style.setAttribute("cssText",str);
else
    obj.setAttribute("style",str);
}

Vediamo un piccolo esempio di applicazione. Il seguente codice invocherà la funzione so_applyStyleString su tutti i div con classe="pullquote" applicando diverse dichiarazioni CSS con una sola chiamata per ciascun elemento:

var s="float:right;width:10em;border:1px dotted #CCC;padding:5px"
var divs=document.getElementsByTagName("div");
for(i=0;i<d.length;i++){
    if(divs[i].className=="pullquote")
        so_applyStyleString(divs[i],s);
    }

Il terzo modo per aggiungere stili CSS mediante Javascript è assegnare una classe CSS agli elementi di pagina: le dichiarazioni CSS relative a tale classe dovranno trovarsi nel CSS incorporato o esterno alla pagina. La proprietà className consente di accedere sia in lettura che in scrittura alle classi CSS attributie sia nel markup che da Javascript stesso. Nel prossimo esempio viene attribuita la classe "open" all'elemento con id="menu":

var el=document.getElementById("menu");
el.className="open";

Da notare che in questo modo si perderà l'informazione di altre eventuali classi assegnate all'elemento nel codice HTML e/o da Javascript stesso. La soluzione accodare la classe aggiungendola alla proprietà className:

var el=document.getElementById("menu");
el.className+=" open";

Nel seguito dell'articolo vedremo tre possibili modi per potenziare quest'approccio aggiungendo CSS esterni in una pagina con o senza l'ausilio di Javascript. Ma prima diamo uno sguardo a come sia possibile accedere in lettura a valori di proprietà CSS mediante Javascript.

La lettura di valori CSS da Javascript

Abbiamo appena visto come sia possibile attribuire valori di proprietà CSS mediante Javascript, ma se tali valori volessimo consultarli in lettura le cose il più delle volte non si rivelano così semplici. Attraverso la proprietà style degli elementi DOM è possibile accedere a proprietà CSS in Javascript. Per esempio, il seguente codice rileva il colore di sfondo del div id="content" e lo assegna alla variabile contentColor:

var el=document.getElementById("content");
var contentColor=el.style.backgroundColor;

C'è da evidenziare che la variabile contentColor conterrà effettivamente un valore non nullo solo se la proprietà CSS è stata in precedenza impostata mediante Javascript. Spesso quindi non disporremo di un dato utile. Ci sono alternative? Il metodo document.defaultView.getComputedStyle del DOM consente proprio di accedere a valori CSS non precedentemente impostati mediante Javascript. Anche in questo caso una piccola differenza con Internet Explorer, che dispone invece del metodo proprietario currentStyle. Ecco quindi la piccola e utile funzione getStyleProp, tratta in parte da Quirksmode e da me leggermente modificata per questioni di compatibilità:

function getStyleProp(x,prop){
if(x.currentStyle)
    return(x.currentStyle[prop]);
if(document.defaultView.getComputedStyle)
    return(document.defaultView.getComputedStyle(x,'')[prop]);
return(null);
}

Da notare che non tutti i valori delle proprietà CSS sono accessibili da Javascript e spesso i valori restituiti dalla funzione sono differenti a seconda del browser. Per esempio, per ciò che riguarda i colori di sfondo e del testo in Internet Explorer questi vengono restituiti in formato esadecimale, in Opera e Firefox/Mozilla in rgb, mentre in Safari nel formato rgba che contiene anche l'informazione sulla trasparenza. Indispensabile quindi una buona fase di test multi-browser se si vuole adottare un simile approccio. Prima di passare al prossimo argomento, segnalo anche la funzione getCSSProp che combina i due modi di accedere in lettura a valori di proprietà CSS qui visti.

Aggiungere CSS esterni con Javascript

Nella maggior parte dei casi di soluzioni Javascript + CSS, si potrebbe adottare un approccio interamente basato su Javascript, grazie al DOM che permette di modificare direttamente la presentazione, aggiungendo proprietà e valori CSS agli elementi di pagina. Ma per quali motivi allora appoggiarsi ai CSS quando si potrebbe fare tutto con Javascript?

Principalmente i motivi sono tre: il primo è che è molto più semplice e leggero attribure nel Javascript una classe, da presentare con i CSS, che aggiungere proprietà e valori direttamente con il DOM. Il secondo motivo è che un simile approccio mantiene i compiti separati: a Javascript spetta gestire eventi e manipolare, creare elementi, mentre i CSS si occupano della presentazione delle pagine arricchite. Dai primi due punti ne consegue il terzo, ovvero un ulteriore grado di personalizzazione che spesso si rivela utilissimo.

Una buona pratica in soluzioni basate su CSS e Javascript è tenere il CSS funzionale e/o presentazionale della soluzione arricchita in un CSS esterno e separato rispetto a quello che riguarda layout e presentazione della pagina senza Javascript. Detto ciò, i modi di procedere sono sostanzialmente tre.

Il primo e più semplice è linkare nella sezione head sia il javascript sia il CSS:

<script type="text/javascript" src="nifty.js"></script>
<link rel="stylesheet" type="text/css" href="nifty.css">

Questa soluzione ha un piccolo svantaggio, ovvero far scaricare all'utente il CSS necessario anche se Javascript non può girare. Gli utenti che navigano con Javascript disabilitato o con browser non DOM-compatibili saranno una percentuale che oscilla tra il 5 e il 10%, ma servire un CSS di cui non potranno beneficiare uno spreco di byte sia per l'utente che per il server.

Il secondo e il terzo approccio linkano il CSS solo nel caso in cui Javascript sia abilitato. Ma come fare? Semplice, basta includere il CSS tramite il javascript stesso: ecco così la seconda soluzione. All'interno del javascript linkato nella sezione head basterà aggiungere la seguente riga:

document.write('<link rel="stylesheet" type="text/css" href="nifty.css">');

Un piccolo accorgimento da tenere in considerazione: ovvero la parità di singoli e doppi apici. Questa soluzione è altrettanto veloce e consente comunque il caching del CSS e si rivela molto efficace soprattutto se vogliamo applicare con effetto quasi immediato regole CSS subordinate alla presenza o meno di Javascript. Lo svantaggio principale è che una soluzione simile non funziona in documenti XML o con pagine XHTML servite con mime-type application/xhtml+xml.

Il terzo approccio supera quest'ultimo problema, ma si presenta un po' più prolisso. Cominciamo con il vedere il codice della funzione AddCSS, che riceve come unico parametro il nome del file CSS, eventualmente con il percorso, e crea un elemento link con gli attributi necessari:

function AddCss(url){
var l=document.createElement("link");
l.setAttribute("type","text/css");
l.setAttribute("rel","stylesheet");
l.setAttribute("href",url);
document.getElementsByTagName("head")[0].appendChild(l);
}

La funzione AddCss, interamente basata sul DOM, non è purtroppo libera da svantaggi. Infatti requisito fondamentale è che questa venga invocata quando il caricamento della pagina è avvenuto, o almeno quando l'elemento head è disponibile nell'albero DOM. Tipicamente, verrà quindi chiamata all'interno del gestore di eventi window.onload: da ciò deriva la mancanza di rapidità di esecuzione che caratterizzava la precedente soluzione.

Conclusioni

Prima di concludere, una citazione en passant va alla collezione document.styleSheets che pur facendo parte delle specifiche DOM di livello 2 del W3C non gode purtroppo di un buon supporto cross-browser. Potenzialmente sarebbe utilissima: consente infatti di consultare, accedere in lettura e scrittura e aggiungere proprietà e valori CSS mediante Javascript, ma come documentato minuziosamente da Peter-Paul Koch il supporto del DOM di livello 2 si rivela piuttosto variabile da browser a browser.

Abbiamo visto in questo articolo come Javascript disponga di metodi consolidati per interagire con i fogli di stile, accedendo in lettura o in scrittura a singole proprietà, aggiungendo classi e addirittura interi fogli di stile. Una cosa da tener ben presente lavorando con Javascript e CSS assieme è la separazione dei ruoli: di norma, non bisogna far fare a Javascript ciò che è compito esclusivo dei CSS, ovvero la presentazione di default. In quanto alla presentazione "arrichita" andrà valutato di caso in caso se lavorare esclusivamente con Javascript porta dei vantaggi in termini di peso e velocità oppure se sacrifica gradi di libertà della sua personalizzazione: in tal caso appoggiarsi a un CSS esterno si rivela il più delle volte la scelta migliore. Alla prossima.

Ti consigliamo anche