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

Icon fonts e Inline SVG

Un confronto pratico tra le due tecniche per la visualizzazione di elementi vettoriali
Un confronto pratico tra le due tecniche per la visualizzazione di elementi vettoriali
Link copiato negli appunti

Una scelta importante nella progettazione della grafica di un sito web riguarda il sistema delle icone. Il valore semantico delle icone, infatti, permette all'utente di orientarsi rapidamente all'interno del sito e di comprendere con un solo colpo d'occhio quali sono i servizi che questo offre.

Dal punto di vista tecnico, le opzioni sono diverse, possiamo decidere di utilizzare immagini rasterizzate, magari adottando la tecnica dei CSS sprites, oppure orientarsi verso il formato vettoriale.

Il sistema delle icone di Yahoo! è concentrato in una sola immagine .png, qui parzialmente visibile su sfondo grigio

Yahoo! sprites

Le immagini vettoriali, rispetto alle bitmap, hanno il considerevole vantaggio di adattarsi perfettamente ad ogni risoluzione, caratteristica importante vista la molteplicità delle periferiche in commercio.

Se si decide per il vettoriale, le alternative sono due: Icon fonts e Inline SVG. In questo articolo faremo un confronto dettagliato tra queste due soluzioni, avviando l'analisi dalle modalità di inserimento delle icone all'interno del documento, prima seguendo la strada degli Icon fonts, poi degli Inline SVG.

Icon Fonts

Questa soluzione prevede il ricorso ad un font i cui caratteri sono costituiti da elementi grafici non testuali:

  • Il browser considera l'immagine come un normale testo;
  • la presentazione a video può essere gestita attraverso l'utilizzo dei fogli di stile, grazie alle proprietà del testo font-size, color, text-shadow, text-align, etc.

In genere le icone sono inserite nel layout in due modi: in aggiunta a un testo (come le icone nei menu), oppure come oggetti grafici a sé stanti.

Icone in un menu di navigazione

Esempio di icone in un menu di navigazione

In pratica l'elemento grafico altro non è che un particolare carattere di un determinato font. Il primo passo da compiere è quindi quello di specificare il font che contiene i simboli che ci interessano. Per questo utilizziamo la regola @font-face, che come è noto ci permette di caricare qualunque font disponibile su server, permettendoci di sfruttare anche tipi di carattere non presenti sul device dell'utente.

Procuriamoci quindi un font che si adatti al progetto grafico del sito. In rete sono disponibili svariati icon fonts, sia con licenza commerciale che gratuiti, tra i quali:

Per l'esempio che segue, utilizziamo il font Foundation Icons. Ecco come includerlo nel CSS:

@font-face {
	font-family: 'foundation-icons';
	src: url('../fonts/foundation-icons.eot');
	src: url('../fonts/foundation-icons.eot?#iefix') format('embedded-opentype'),
		url('../fonts/foundation-icons.woff') format('woff'),
		url('../fonts/foundation-icons.ttf') format('truetype'),
		url('../fonts/foundation-icons.svg#fontcustom') format('svg');
	font-weight: normal;
	font-style: normal;
}

Proprietà Descrizione
font-family stabilisce il nome del font (che può anche essere diverso dal nome del file)
src individua la URL del file, nella forma url(...), o il nome del font locale, nella forma local('Font name')
font-weight font-style impostano i valori delle rispettive proprietà del carattere

La proprietà src può assumere diversi valori: in particolare, è bene specificare più formati di file, in modo da garantire il massimo supporto da parte di tutti i browser. Tra questi formati, attualmente quello che offre maggiori possibilità di impiego è il formato woff, sviluppato da Mozilla e supportato da quasi tutti i browser di riferimento.

Una volta definito, il font è disponibile per essere incorporato nel documento. Il carattere-icona potrà essere inserito subito prima dell'etichetta del link, grazie alla notazione :before, che crea uno pseudo elemento come primo discendente dell'elemento selezionato. Il compito principale è, quindi, quello di selezionare l'elemento del DOM in cui dovrà essere inserita l'icona. L'elemento può essere individuato grazie ad un nome di classe, come nel markup che segue:

<ul class="icons size-4">
  <li><a href="#"><span aria-hidden="true" class="fi-social-drive"></span>Drive</a></li>
  <li><a href="#"><span aria-hidden="true" class="fi-social-dropbox"></span>Dropbox</a></li>
  <li><a href="#"><span aria-hidden="true" class="fi-social-evernote"></span>Evernote</a></li>
</ul>

Gli span dell'esempio vengono assegnati a specifiche classi i cui stili saranno definiti più avanti. L'attributo aria-hidden ha lo scopo di rendere invisibile l'elemento per gli screen readers, come il VoiceOver di iOS.

Nel file .css, quindi, definiamo due blocchi di dichiarazioni, il primo dei quali assegna le caratteristiche del font:

...
.fi-social-drive:before,
.fi-social-dropbox:before,
.fi-social-evernote:before {
	font-family: 'foundation-icons';
	font-style: normal;
	font-weight: normal;
	font-variant: normal;
	text-transform: none;
	line-height: 1;
	-webkit-font-smoothing: antialiased;
	display: inline-block;
	text-decoration: inherit;
}

Assegnamo il font che abbiamo dichiarato con il @font-face agli pseudo-elementi :before delle classi fi-social-drive, fi-social-dropbox, fi-social-evernote.

Il secondo blocco di dichiarazioni inserisce il carattere individuato dalla proprietà content in codifica Unicode:

.fi-social-drive:before    { content: 'f1c1'; }
.fi-social-dropbox:before  { content: 'f1c2'; }
.fi-social-evernote:before { content: 'f1c3'; }

Foundation Icons

Foundation Icons

Il codice appena visto è fornito con il file foundation-icons.css, che può essere, quindi, incorporato separatamente, oppure riportato all'interno del foglio di stile del sito. In quest'ultimo andrà rifinito il layer grafico con le dichiarazioni che seguono:

.icons {
	padding: 0;
	margin: 0;
	list-style: none;
}
.icons li    { line-height: 1.2em; }
.icons a     { text-decoration: none; color: #000; }
.icons a span{ text-decoration: none; padding-right: .4em; }
.size-2 { font-size: 2em; }
.size-3 { font-size: 3em; }
.size-4 { font-size: 4em; }

padding-right impone una spaziatura sulla destra, in modo che l'elemento selezionato si discosti dall'elemento successivo. Le classi size-n impostano dimensioni alternative dei caratteri.

Ecco l'esempio dal vivo, il codice completo è in allegato.

“Foundation Icons” dispone di 282 icone, che quindi possono essere inserite all'interno di qualunque elemento inline del sito. Il pacchetto comprende un file preview.html, in cui vengono forniti i nomi delle classi e la codifica Unicode per ognuno dei simboli del font.

Impostare le icone con i CSS su attributo data-

Per ognuna delle 282 icone è definita una classe CSS. Una soluzione più sintetica in termini di CSS prevede il ricorso all'attributo data-icon. Si cambi, quindi, il markup del menu come segue:

<li><a href="#"><span aria-hidden="true" data-icon="&#xf1c1;"></span>Drive</a></li>
<li><a href="#"><span aria-hidden="true" data-icon="&#xf1c2;"></span>Dropbox</a></li>
<li><a href="#"><span aria-hidden="true" data-icon="&#xf1c3;"></span>Evernote</a></li>

Nel foglio di stile, gli elementi verranno selezionati non più tramite il selettore di classe, ma grazie all'attributo data-icon. Questa soluzione prevede che la proprietà content sia assegnata in base al valore dell'attributo data-icon di ognuno degli elementi del menu.

[data-icon]:before
{
	font-family: 'foundation-icons';
	content: attr(data-icon);
	speak: none;
	font-weight: normal;
	font-variant: normal;
	text-transform: none;
	line-height: 1;
	-webkit-font-smoothing: antialiased;
	-moz-osx-font-smoothing: grayscale;
	padding-right: .4em;
}

Questa seconda soluzione, sebbene più sintetica, richiede maggiore attenzione quando si aggiungono nuovi elementi: per ogni icona inserita nel documento, bisognerà individuare il corrispondente codice Unicode e inserirlo come valore dell'attributo data-icon; le classi, al contrario, vanno dichiarate una sola volta.

In questo secondo esempio, il ricorso alla proprietà speak: none, non ancora parte della specifica, ha lo scopo di impedire agli screen readers l'accesso all'elemento (in pratica la stessa funzione dell'attributo aria-hidden).

Il risultato a video, comunque, è esattamente lo stesso rispetto all'esempio precedente.

Nella seconda parte dell'articolo vedremo come lavorare con l'Inline SVG.

Inline SVG

Per introdurre elementi vettoriali all'interno della pagina la tecnica degli Inline SVG è tra le più interessanti e offre diverse soluzioni tecniche per l'inserimento di immagini nel documento.

Anzitutto, rimanendo nell'ambito del confronto con la tecnica degli icon fonts bisogna dire, per la precisione, che i font non sono resi vettorialmente, ma semplicemente ottimizzati come caratteri testuali. Qualora si valuti indispensabile una perfetta resa a video, diventa senza dubbio preferibile ricorrere alla tecnica degli Inline SVG.

Una prima soluzione prevede l'inserimento del codice che genera ogni singola icona all'interno di ogni elemento del DOM destinato ad ospitarla. Così, l'icona di Google Drive utilizzata nell'esempio precedente, dovrebbe essere iniettata nell'elemento <li> corrispondente nel seguente modo:

<li><a href="#">
<svg
	version="1.1"
	id="Layer_1"
	xmlns="http://www.w3.org/2000/svg"
	xmlns:xlink="http://www.w3.org/1999/xlink"
	x="0px"
	y="0px"
	width="100px"
	height="100px"
	viewBox="0 0 100 100"
	enable-background="new 0 0 100 100"
	xml:space="preserve">
<g>
	<polygon fill="#050708" points="40.588,59.659 27.579,82.03 74.491,82.03 87.5,59.659"/>
	<polygon fill="#050708" points="85.952,58.379 62.496,17.753 36.617,17.672 60.073,58.3"/>
	<polygon fill="#050708" points="35.956,19.249 12.5,59.876 25.37,82.328 48.826,41.701"/>
</g>
</svg>
</li>

Il codice è preso dal file fi-social-drive.svg compreso nel pacchetto di Foundation Icons.

SVG Sprite

Una soluzione più efficiente è quella degli SVG sprite, una tecnica che permette di dichiarare gli elementi SVG in un solo punto del DOM, come first-child del body, richiamando, poi, le immagini ovunque queste siano necessarie. Uno sprite è quindi un insieme di elementi SVG raggruppati, definiti ognuno all'interno di un elemento <g> dotato di un identificatore unico, come nell'esempio che segue:

<svg
	display="none"
	version="1.1"
	xmlns="http://www.w3.org/2000/svg"
	xmlns:xlink="http://www.w3.org/1999/xlink"
	width="102"
	height="32"
	viewBox="0 0 102 32">
<defs>
<g id="icon-drive">
	<path class="path1" d=" ... "></path>
</g>
<g id="icon-dropbox">
	<path class="path1" d=" ... "></path>
</g>
...

Si noti l'attributo display="none" dell'elemento svg. Una volta definite le immagini, ognuna di esse potrà essere inserita in qualunque parte del documento, come nell'elenco già analizzato nell'esempio degli icon fonts (si rinvia all'esempio in allegato per il listato completo):

<ul class="icons size-2">
	<li><a href="#"><svg class="icon icon-drive" viewBox="0 0 24 32"><use xlink:href="#icon-drive"></use></svg>Drive</a></li>
	<li><a href="#"><svg class="icon icon-dropbox" viewBox="0 0 25 32"><use xlink:href="#icon-dropbox"></use></svg>Dropbox</a></li>
	<li><a href="#"><svg class="icon icon-evernote" viewBox="0 0 21 32"><use xlink:href="#icon-evernote"></use></svg>Evernote</a></li>
</ul>

Le immagini appariranno sulla sinistra di ogni elemento della lista, grazie all'elemento <use>, il quale duplica gli elementi definiti all'interno del documento SVG in qualunque parte del DOM.
Questa soluzione ha il pregio dell'efficienza, in quanto rende più pulito il codice ed evita duplicazioni nel caso in cui un'icona debba essere visualizzata più volte nella pagina.

Si è detto che uno sprite è costituito da un gruppo di elementi SVG. Se non si desidera cimentarsi in un lavoro di assemblaggio manuale o ricorrere ad un programma di grafica come Adobe Illustrator o Inkscape, può essere estremamente utile il servizio offerto da IcoMoon, la cui applicazione online permette di caricare i font in formato SVG e scaricare uno sprite pronto per essere incorporato nel documento.

Il font Elegant Icons importato su IcoMoon per generare uno sprite SVG

Elegant Icons su IcoMoon

Il codice illustrato qui sopra è stato ottenuto proprio grazie all'applicazione di IcoMoon.
Al file style.css si dovranno ora aggiungere le dichiarazioni specifiche degli elementi SVG:

.icon {
	display: inline-block;
	vertical-align: text-top;
	padding-right: .3em;
	fill: #000000;
}
.size-2 .icon{ width: 32px; height: 32px; }
.size-4 .icon{ width: 64px; height: 64px; }
.icon-drive    { fill: #000000; }
.icon-dropbox  { fill: #000000; }
.icon-evernote { fill: #F000FF; }

E ora non rimane altro che apprezzare il risultato del formato vettoriale.

Il font Foundation Icons inserito nel documento come Inline SVG

Il font Foundation Icons inserito nel documento come Inline SVG

L'esempio dal vivo e il codice da scaricare.

Nella terza parte dell'articolo tireremo le somme mettendo a confronto diretto Icon Fonts e SVG ed esaminando vantaggi e svantaggi delle due tecniche.

Diversi sono i criteri in base ai quali mettere a confronto Icon Fonts e SVG, dalla risoluzione degli elementi grafici, ai problemi cross-orgin.

Risoluzione

Il primo criterio riguarda la risoluzione a video. Gli icon fonts vengono considerati dai browser come normale testo, quindi i bordi sono ammorbiditi con effetto antialias, ma non gestiti come il formato vettoriale. La risoluzione, pertanto, non è ottimale come nel caso delle icone SVG.

Icon Fonts e Inline SVG a confronto

Icon Fonts e Inline SVG a confronto

Controllo dello stile

Un secondo criterio di confronto riguarda il controllo dello stile. L'aspetto degli icon fonts può essere gestito attraverso tutte le proprietà CSS del testo: color, font-size, ombre, rotazione, orientamento, ecc. Il limite è dato proprio da ciò che si può raggiungere attraverso questi strumenti. Non si ha, quindi, il controllo completo dell'aspetto delle icone: non è possibile, ed esempio, un riempimento sfumato, come non è agevole lavorare sui contorni delle immagini.

Il controllo sull'aspetto delle immagini SVG, invece, è estremamente preciso: oltre a tutte le proprietà CSS del testo, lo sviluppatore ha a disposizione le proprietà grafiche specifiche degli oggetti SVG. Queste possono essere definite sia come attributi degli elementi, sia come proprietà CSS. Ad esempio, la grafica dell'icona #icon-drive può essere definita all'interno dell'elemento:

<g id="icon-drive">
<path class="path1" d="..." fill="#AF0" stroke="#000" stroke-width="1"></path>
</g>

Oppure con separate dichiarazioni CSS:

<style>
<![CDATA[
.icon-drive {
	fill:#AF0;
	stroke:#000;
	stroke-width:1;
}
]]>
</style>
<g id="icon-drive">
	<path class="path1" d="..."></path>
</g>

Il blocco <![CDATA[...]]> è necessario quando le dichiarazioni si riferiscono ad elementi SVG per evitare che, eventuali caratteri > nelle dichiarazioni, possano generare errori in fase di parsing.

Per tenere separati gli stili degli elementi SVG, è possibile anche ricorrere ad un file .css specifico, incorporato nel documento prima dell'elemento svg, come nell'esempio che segue:

<?xml-stylesheet type="text/css" href="css/svg-style.css" ?>
<svg display="none" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="102" height="32" viewBox="0 0 102 32">

Posizionamento e dimensioni

Nel caso degli icon fonts, il posizionamento delle icone viene influenzato dalle proprietà del testo: line-height, vertical-align, letter-spacing, word-spacing. Per avere un maggior controllo, potrebbe essere necessario ricorrere alla proprietà display.

Molto più immediata, invece, è la gestione delle icone SVG: di queste vanno semplicemente specificate larghezza, altezza, posizionamento orizzontale e verticale.

Problemi di origine

Il ricorso agli icon fonts può portare ad inconvenienti non sempre prevedibili. Sia Firefox che Internet Explorer non permettono che i font vengano caricati da server diversi, nel rispetto della Same Origin Policy.

Un modo di aggirare il problema è quello di consentire il caricamento di specifici tipi di file, aggiungendo la seguente istruzione al file .htaccess o al file httpd.conf (se si opera su server Apache):

<FilesMatch ".(eot|ttf|otf|woff)">
	Header set Access-Control-Allow-Origin &quot;*&quot;
</FilesMatch>

Nessun problema di origine, al contrario, per gli elementi SVG, dato che questi sono codificati direttamente all'interno del documento.

Supporto

Sia icon fonts che inline SVG non sono universalmente supportati. Gli icon fonts, ad esempio, dipendono dal supporto della regola @font-face, e potrebbero non essere visualizzati per niente nel caso di browser obsoleti.

Migliore il supporto degli inline SVG, sebbene anche qui i browser obsoleti non offrano le dovute garanzie.

In entrambi i casi è sempre prudente prevedere soluzioni di fallback, magari ricorrendo all'ormai indispensabile ausilio dello script Modernizr.

Consumo di risorse

Nel caso degli icon fonts, il caricamento di un intero set di due o trecento caratteri potrebbe comportate uno spreco eccessivo di risorse. Considerazione più che plausibile, soprattutto nel caso delle connessioni mobili. Tuttavia, con un'accorta progettazione grafica o con il ricorso a strumenti come IcoMoon, è possibile ridurre al minimo il numero di caratteri da incorporare, senza quindi dover caricare l'intero set. Questa riflessione non è necessaria, invece, per gli inline SVG, definiti direttamente all'interno del documento e solo ove necessari.

Qual tecnologia preferire?

Gli SVG si fanno preferire praticamente per tutti gli aspetti considerati, anche se, con i dovuti accorgimenti, gli icon fonts possono fornire comunque una buona soluzione tecnica, sia in termini di risoluzione, sia in termini di semplicità d'uso.

Link Utili

Ti consigliamo anche