Come usare una libreria di icone SVG
Con il diffondersi di siti web responsive fruibili da vari dispositivi con varie risoluzioni, diventa sempre più importante sostituire le immagini classiche in png o jpg con formati vettoriali come svg.
Per sua natura il formato svg è scalabile all'infinito senza perdere definizione.
Un immagine svg può essere inserita direttamente nella pagina html con il tag svg o con il tag img:
in questo caso una stella bianca e rossa:
Tramite il tag symbol è possibile definire una o più immagini all'interno delle stesso tag svg in modo da creare una libreria di immagini riutilizzabili più volte nella stessa pagina.
Questo è un esempio con più immagini:
da notare che questo codice non produce nessun render a video.
e referenziare l'id associato al symbol della libreria tramite l'attibuto href e il carattere cancelletto #, nella forma href="#id".
essendo un formato vettoriale posso visualizzare le immagini con varie dimensioni senza perdere definizione.
Posso anche spostare la definizione della libreria in un file esterno:
e referenziare i simboli con la forma nomefile#id:
in questo modo non appesantisco la pagina, sfrutto il caching dei browser e, avendo una libreria con più simboli, ottimizzo il numero di connessioni che il browser deve aprire per recuperare le immagini.
e poi referenziare i simboli senza nome file
Il file completo con tutte le casistiche:
Image library svg - Sgart.it
Vedi anche An in-depth SVG tutorial
Per sua natura il formato svg è scalabile all'infinito senza perdere definizione.
Un immagine svg può essere inserita direttamente nella pagina html con il tag svg o con il tag img:
XML
<!-- stella bianca -->
<svg style="fill:#fff" width="16" height="16">
<path d="M6 .3l1.5 4.3 4.5.1-3.6 2.7 1.3 4.3L6 9.1l-3.7 2.6 1.3-4.3L0 4.7l4.5-.1z"></path>
</svg>
<!-- stella rossa -->
<img src="sgart-img0.svg" width="16" height="16">
Il tag svg path permette di definire una figura tramite una serie di coordinate di punti sul piano X / Y e una serie di comandi (M, l, L, z, ecc...)
Nel tag img posso anche inserire il codice xml dell'svg:XML
<img src="data:image/svg+xml;charset=utf8,%3Csvg version='1.1' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M6 .3l1.5 4.3 4.5.1-3.6 2.7 1.3 4.3L6 9.1l-3.7 2.6 1.3-4.3L0 4.7l4.5-.1z' fill='%23ff0000'%3E%3C/path%3E%3C/svg%3E" width="16" height="16">
in questo caso devo applicare un url encoding, sostituire le doppie virgolette con il singolo apice e far precedere il tutto dalla stringa data:image/svg+xml;charset=utf8,
Tramite il tag symbol è possibile definire una o più immagini all'interno delle stesso tag svg in modo da creare una libreria di immagini riutilizzabili più volte nella stessa pagina.
Questo è un esempio con più immagini:
XML
<b>definizione libreria, nessun render</a>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" class="hidden">
<symbol id="star1" viewBox="0 0 20 20">
<path d="M6 .3l1.5 4.3 4.5.1-3.6 2.7 1.3 4.3L6 9.1l-3.7 2.6 1.3-4.3L0 4.7l4.5-.1z" fill="#ffffff"></path>
</symbol>
<symbol id="alert1" viewBox="0 0 50 50">
<path d="M43.327 0H6.275C2.611-.02 0 2.188 0 5.839v26.218c0 3.706 2.661 6.985 6.329 7.029l13.383.025L30.702 49.9l.082-10.758h12.441c3.661.03 6.664-2.933 6.664-6.594l.056-26.317C49.97 2.59 46.993 0 43.327 0" fill="#ff0000"></path>
<path d="M28.611 27.92a3.666 3.666 0 1 1-7.332 0 3.666 3.666 0 0 1 7.332 0M25.636 6.305h-3.597l.918 15.932h4.326l.919-15.932z" fill="#ffffff"></path>
</symbol>
</svg>
Ogni simbolo deve avere l'attributo id e viewBox
Per visualizzare una delle immagini contenute nella libreria devo usare il tag use:XML
<svg width="150" height="150">
<use xlink:href="#star1" href="#star1" />
</svg>
<svg width="15" height="15">
<use xlink:href="#star1" href="#star1" />
</svg>
<svg width="50" height="50">
<use xlink:href="#alert1" href="#alert1" />
</svg>
L'attributo xlink:href è deprecato a favore di href, vedi xlink:href
definizione libreria, nessun reder
referenzio i siboli tramite l'id
essendo un formato vettoriale posso visualizzare le immagini con varie dimensioni senza perdere definizione.
Posso anche spostare la definizione della libreria in un file esterno:
XML: sgart-img.svg
<svg version="1.1" xmlns="http://www.w3.org/2000/svg">
<symbol id="star" viewBox="0 0 20 20">
<path d="M6 .3l1.5 4.3 4.5.1-3.6 2.7 1.3 4.3L6 9.1l-3.7 2.6 1.3-4.3L0 4.7l4.5-.1z"></path>
</symbol>
<symbol id="alert" viewBox="0 0 50 50">
<path d="M43.327 0H6.275C2.611-.02 0 2.188 0 5.839v26.218c0 3.706 2.661 6.985 6.329 7.029l13.383.025L30.702 49.9l.082-10.758h12.441c3.661.03 6.664-2.933 6.664-6.594l.056-26.317C49.97 2.59 46.993 0 43.327 0"></path>
<path d="M28.611 27.92a3.666 3.666 0 1 1-7.332 0 3.666 3.666 0 0 1 7.332 0M25.636 6.305h-3.597l.918 15.932h4.326l.919-15.932z"></path>
</symbol>
</svg>
HTML
<svg>
<use href="./sgart-img.svg#star" />
</svg>
Questa funzionalità, che permette di referenziare i simboli in un file esterno, non è supportata da Internet Explorer fino alla versione 11 compresa
Se dobbiamo supportare internet explorer e l'uso dei file di simboli, lo si può ottenere tramite una chiamata AJAX:JavaScript
//solo per Internet Explorer
function loadSvg() {
var req = new XMLHttpRequest();
req.open("GET", "sgart-img2.svg", true);
req.send();
req.onload = function (e) {
var div = document.createElement("div");
div.setAttribute("style", "display:none;");
div.innerHTML = req.responseText;
document.body.insertBefore(div, document.body.childNodes[0]);
}
}
document.addEventListener('DOMContentLoaded', loadSvg, false);
XML
<svg>
<use href="#star" />
</svg>
Il file completo con tutte le casistiche:
HTML
<html>
<head>
<title>Image library svg - Sgart.it</title>
<style>
.svg {
fill: #000;
width: 30px;
height: 30px;
}
.svg svg {
width: 30px;
height: 30px;
}
.hidden {
display: none;
}
</style>
</head>
<body>
<h1>test svg href (non funziona in IE 11)</h1>
<div class="svg">
<svg>
<use href="./sgart-img.svg#star" /></svg>
</div>
<div class="svg">
<svg>
<use xlink:href="sgart-img.svg#alert" href="img.svg#alert" /></svg>
</div>
<hr>
<h1>test svg embed</h1>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" class="hidden">
<symbol id="star1" viewBox="0 0 20 20">
<path d="M6 .3l1.5 4.3 4.5.1-3.6 2.7 1.3 4.3L6 9.1l-3.7 2.6 1.3-4.3L0 4.7l4.5-.1z"></path>
</symbol>
<symbol id="alert1" viewBox="0 0 50 50">
<path d="M43.327 0H6.275C2.611-.02 0 2.188 0 5.839v26.218c0 3.706 2.661 6.985 6.329 7.029l13.383.025L30.702 49.9l.082-10.758h12.441c3.661.03 6.664-2.933 6.664-6.594l.056-26.317C49.97 2.59 46.993 0 43.327 0"></path>
<path d="M28.611 27.92a3.666 3.666 0 1 1-7.332 0 3.666 3.666 0 0 1 7.332 0M25.636 6.305h-3.597l.918 15.932h4.326l.919-15.932z"></path>
</symbol>
</svg>
<div class="svg">
<svg>
<use xlink:href="#star1" href="#star1" /></svg>
</div>
<div class="svg">
<svg>
<use xlink:href="#alert1" href="#alert1" /></svg>
</div>
<hr>
<h1>test svg load async</h1>
<div class="svg">
<svg>
<use xlink:href="#star2" href="#star2" /></svg>
</div>
<div class="svg">
<svg>
<use xlink:href="#alert2" href="#alert2" /></svg>
</div>
<hr>
<img src="sgart-img0.svg">
<script>
function loadSvg() {
var req = new XMLHttpRequest();
req.open("GET", "sgart-img2.svg", true);
req.send();
req.onload = function (e) {
var div = document.createElement("div");
div.setAttribute("style", "display:none;");
div.innerHTML = req.responseText;
document.body.insertBefore(div, document.body.childNodes[0]);
}
}
document.addEventListener('DOMContentLoaded', loadSvg, false);
</script>
</body>
</html>
test svg href (non funziona in IE 11)
test svg embed
test svg load async
Vedi anche An in-depth SVG tutorial