Formato vettoriale, dimensioni ridotte dei file, adattabilità a schermi di qualsiasi dimensione e risoluzione, sono le caratteristiche principali del linguaggio di markup la cui prima specifica risale al 1999.
Nonostante gli anni, SVG si sta imponendo tra gli sviluppatori per l'adattabilità ad ogni tipo di periferica, soprattutto se mobili e con limitate capacità di elaborazione.
Data la premessa, con questa guida vedremo come approfittare delle funzionalità del linguaggio per dotare pagine e applicazioni web delle caratteristiche più avanzate, grazie all'impiego congiunto di SVG e CSS.
La stessa immagine SVG a diverse risoluzioni
Quando utilizzare SVG
Spesso, per ottenere dinamicamente immagini o generare animazioni, si ricorre a strumenti fortemente orientati a JavaScript, come l'elemento canvas
di HTML5. Tuttavia non è detto che la coppia Canvas+JavaScript offra sempre la soluzione migliore.
Sul canvas, disegnare un'immagine è un compito che non può essere eseguito senza programmare. Al contrario, creare un'immagine SVG è un compito che può essere ampiamente delegato ad uno dei vari tool grafici disponibili, senza dover scrivere una sola riga di codice. Il primo pregio degli SVG, dunque, è la semplicità di creazione.
Le immagini SVG sono oggetti XML. Per questo dispongono di un DOM a cui è possibile accedere nello stesso modo in cui si accede al DOM di un documento HTML. Per cambiare dinamicamente il colore di una linea, ad esempio, basta cambiare via JavaScript il valore dell'attributo stroke
o della corrispondente proprietà CSS. Per lo stesso motivo, le immagini SVG possono essere generate o modificate dinamicamente tramite un linguaggio lato server.
Anche dal lato SEO, SVG presenta vantaggi: il markup è interpretato dalla macchina e permette una corretta indicizzazione nei motori di ricerca, al contrario di quanto sia possibile sia ricorrendo all'elemento canvas, sia alle (ormai vecchie) animazioni Flash.
Ma SVG non è una soluzione universale. Sul piano della performance, infatti, il canvas
si fa preferire, soprattutto quando gli elementi che compongono l'oggetto sono numerosi, come nel caso dei videogames.
Fatto salvo il problema delle prestazioni in animazioni complesse, SVG si presenta come una soluzione ottimale per la generazione di loghi e diagrammi, dove le animazioni non assorbono una gran quantità di risorse.
La specifica SVG 1.1 del W3C prevede 14 funzionalità principali: forme base (linee, poligoni, cerchi, ellissi e rettangoli), percorsi, testo, elementi grafici, colori, sfumature e modelli, ritagli, maschere e composizioni, filtri, collegamenti ipertestuali, interattività via JavaScript, manipolazione del DOM, animazioni, font e metadati.
A queste funzionalità aggiungiamo quella costituisce il tema centrale di questa guida: SVG supporta CSS per la gestione grafica degli oggetti.
Il supporto dei browser
Il supporto è abbastanza ampio, almeno per quanto riguarda i browser più recenti. Tutti, infatti, offrono quanto meno il supporto base ad SVG. Alcune funzionalità non sono ancora generalizzate, come i font SVG, ma non si tratta delle feature principali. In ogni caso, la rapida diffusione e le promettenti possibilità di applicazione, fanno di SVG una delle tecnologie web più attuali.
I font SVG sono scarsamente supportati dai maggiori browser (fonte Caniuse)
Già ora è possibile visualizzare SVG come file separato nella finestra di un browser; è possibile includerlo all'interno di un documento HTML; definirlo come risorsa esterna degli elementi img
, object
, embed
o iframe
; impostarlo come immagine di background con CSS.
Inserire SVG all'interno delle pagine HTML
È possibile inserire oggetti SVG nelle pagine HTML in diversi modi. Non tutti sono in alternativa, essendo alcuni finalizzati al raggiungimento di specifici obiettivi.
Elemento SVG e l'inserimento in modalità inline
Anzitutto gli elementi SVG possono essere inclusi grazie al tag svg, anche in modalità inline, ossia inserendo il codice direttamente all'interno del documento HTML. Quello che segue è un testo SVG in un elemento div
:
<div>
<svg xmlns="http://www.w3.org/2000/svg" width="180px" height="68px">
<text x="10" y="60" font-size="80">SVG</text>
</svg>
</div>
Questa soluzione permette un agevole accesso alla struttura dell'oggetto via JavaScript o CSS, bisogna solo fare attenzione alla crescita della complessità del documento principale quando pensiamo di incorporare oggetti complessi. Sicuramente ottima per forme semplici.
La direzione che si sta seguendo è quella di implementare sempre meglio l'elemento svg, che ci consente di utilizzare forme definite altrove all'interno del documento:
<svg viewBox="0 0 100 100">
<use xlink:href="#forma-1"></use>
</svg>
Possiamo anche includere svg file esterni (ma per questo meglio controllare il supporto dei browser su caniuse):
<svg viewBox="0 0 100 100">
<use xlink:href="forme.svg#icon-1"></use>
</svg>
SVG come elemento object
Un file SVG può essere incorporato tramite un elemento object. Questa soluzione è quella da preferire per accedere al DOM dell'oggetto via JavaScript o per assegnare stili CSS ai suoi elementi. Quello che segue è un semplice esempio:
<object type="image/svg+xml" id="logo" data="SVGLogo.svg">
<div>SVG logo</div>
</object>
Nel div
inseriamo il testo da visualizzare dai browser che non supportano le funzionalità SVG di base (Explorer 8 e versioni precedenti).
SVG con embed
Come alternativa all'elemento object
, sebbene non faccia parte della specifica, l'elemento embed è supportato da tutti i browser e può essere utilizzato in modo simile:
<embed type="image/svg+xml" src="SVGLogo.svg" />
SVG con iframe
Una terza soluzione, di nuovo aderente agli standard, prevede il ricorso all'elemento iframe
:
<iframe src="SVGLogo.svg">
<img src="SVGLogo64.png" alt="SVG logo" />
</iframe>
Anche in questo caso, l'elemento img
fornisce una soluzione di emergenza per i browser obsoleti.
object
e iframes
non presentano differenze sostanziali se non si rende necessario l'accesso ad SVG via JavaScript e/o CSS. In questi casi l'elemento object
si fa preferire rispetto ad iframe
per la maggiore praticità, essendo incorporato all'interno del documento principale.
SVG con IMG, come immagini
Gli SVG possono anche essere inseriti come normali immagini:
<div id="logo">
<img src="SVGLogo.svg" alt="SVG logo" />
</div>
In questo caso, però, nonostante la semplicità, motivi di sicurezza impongono una serie di restrizioni:
- il documento SVG non può caricare risorse esterne, come script, fogli di stile e immagini;
- non possono essere caricati font esterni;
- non possono essere eseguiti script;
- sono disabilitati gli event listener.
A parte questi limiti, sono sempre ammesse le animazioni, sia SVG che CSS. L'inserimento tramite img è attualmente supportato da tutti i browser.
SVG come sfondo nei CSS
Un'ultima soluzione è specifica per l'utilizzo degli oggetti SVG come immagini di sfondo:
#element{
background-image: url(background.svg);
}
Anche in questo caso, come per l'elemento img, il browser disabilita ogni tipo di interazione. Questa soluzione è supportata da tutti i maggiori browser.
Soluzioni di fallback
Come si è detto, Explorer 8 non supporta SVG. Per ognuna delle modalità segnalate, esistono soluzioni alternative che permettono di evitare errori nella visualizzazione della pagina.
Markup alternativo
Nel primo esempio, all'interno dell'elemento object è stato inserito un div
con un testo alternativo. In realtà si sarebbe potuta inserire anche un'immagine in un formato supportato. Tuttavia l'immagine sarebbe stata caricata anche dai browser che visualizzano correttamente l'immagine SVG, con inutile spreco di risorse.
Una soluzione più efficiente prevede l'inserimento dell'immagine via CSS, solo in caso di necessità:
<style>
#logo div{
width: 128px;
height: 128px;
background-image: url(SVGLogo.png);
}
</style>
<object type="image/svg+xml" id="logo" data="SVGLogo.svg">
<div>SVG logo</div>
</object>
Modernizr
Nel caso del ricorso all'elemento img, Chris Coyer, suggerisce il ricorso a Modernizr e jQuery:
if (!Modernizr.svg) {
$("#logo img").attr("src", "SVGLogo.png");
}
Una diversa soluzione prevede l'inserimento nel markup di un paio di istruzioni JavaScript:
<img src="SVGLogo.svg" onerror="this.onerror=null; this.src='SVGLogo.png'">
Sfruttando sempre le funzionalità di Modernizr, è possibile prevedere una soluzione alternativa anche nel caso degli sfondi SVG. In questo caso basta un blocco di dichiarazioni CSS:
.no-svg #element{
background-image: url(background.png);
}
Qui la classe no-svg
viene generata da Modernizr sull'elemento html
nel caso manchi il supporto del browser, permettendo l'assegnazione di stili specifici.
Conclusioni e Riferimenti
Tra le varie soluzioni presentate, l'inserimento degli SVG tramite l'elemento object
sembra offrire maggiori garanzie di compatibilità e permette di accedere agli elementi sia tramite JavaScript che CSS. Per le immagini statiche, l'elemento img
e l'utilizzo dei background sono soluzioni ugualmente praticabili. Per i puristi degli standard è sconsigliato l'elemento embed
, mentre appare poco pratico l'elemento iframe
.
Di seguito si riportano le risorse ufficiali del W3C, e non, cui si è fatto riferimento:
- Scalable Vector Graphics (SVG) 1.1 (Second edition)
- SVG Security
- Mobile SVG profiles: SVG Tiny and SVG Basic
- Scalable Vector Graphics (SVG) Tiny 1.2 Specification
- La prima specifica del 1999
Infine, segnaliamo ancora: