Introduzione
Quando un sito utilizza molte icone SVG, copiare ogni volta l’intero markup dell’icona può rendere il codice HTML lungo, difficile da mantenere e soggetto a incoerenze. Una soluzione pratica consiste nel creare uno sprite SVG: un contenitore che raccoglie più simboli riutilizzabili all’interno della pagina.
Ogni icona viene definita tramite l’elemento <symbol> e richiamata dove serve con <use>. In questo modo la geometria dell’icona viene dichiarata una sola volta, mentre ogni istanza può avere dimensioni, colori e attributi di accessibilità differenti.
Questo approccio è particolarmente utile per:
- dashboard con molte icone ripetute;
- menu di navigazione e pulsanti di azione;
- interfacce con tema chiaro e scuro;
- componenti HTML che devono mantenere una struttura coerente;
- progetti in cui le icone devono essere aggiornate da un unico punto.
Lo sprite può essere inserito direttamente nell’HTML, normalmente all’inizio del contenuto della pagina. I simboli rimangono invisibili, mentre vengono visualizzati solo nei punti in cui sono referenziati.
Codice completo
<!-- Sprite SVG: contiene le definizioni riutilizzabili delle icone -->
<svg
aria-hidden="true"
width="0"
height="0"
style="position: absolute;"
>
<defs>
<symbol id="icon-search" viewBox="0 0 24 24">
<circle
cx="10.5"
cy="10.5"
r="6.5"
fill="none"
stroke="currentColor"
stroke-width="2"
/>
<path
d="M16 16l5 5"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
/>
</symbol>
<symbol id="icon-check" viewBox="0 0 24 24">
<path
d="M5 12.5l4.5 4.5L19 7.5"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
/>
</symbol>
<symbol id="icon-chevron-right" viewBox="0 0 24 24">
<path
d="M9 5l7 7-7 7"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
/>
</symbol>
</defs>
</svg>
<main>
<h2>Ricerca prodotti</h2>
<button type="button">
<svg
width="20"
height="20"
viewBox="0 0 24 24"
aria-hidden="true"
focusable="false"
>
<use href="#icon-search"></use>
</svg>
<span>Cerca</span>
</button>
<p>
<svg
width="20"
height="20"
viewBox="0 0 24 24"
role="img"
aria-labelledby="check-title"
focusable="false"
>
<title id="check-title">Operazione completata</title>
<use href="#icon-check"></use>
</svg>
Profilo aggiornato correttamente.
</p>
<a href="/prodotti">
Visualizza tutti i prodotti
<svg
width="18"
height="18"
viewBox="0 0 24 24"
aria-hidden="true"
focusable="false"
>
<use href="#icon-chevron-right"></use>
</svg>
</a>
</main>
Spiegazione
Definire i simboli
L’elemento <symbol> rappresenta una grafica riutilizzabile, ma non viene visualizzato autonomamente. L’attributo id identifica il simbolo e permette di richiamarlo. Per esempio, id="icon-search" crea il riferimento utilizzato successivamente con href="#icon-search".
L’attributo viewBox="0 0 24 24" stabilisce il sistema di coordinate interno. Non determina direttamente la dimensione mostrata: questa viene controllata dagli attributi width e height dell’istanza SVG.
Usare sempre lo stesso viewBox, come il formato 24 × 24 dell’esempio, aiuta a mantenere uniformi le proporzioni delle icone.
Richiamare un’icona con <use>
L’elemento <use> crea un’istanza del simbolo. La sintassi più moderna è:
<use href="#icon-search"></use>
È possibile incontrare anche la forma precedente xlink:href, ma nei browser moderni href è generalmente sufficiente. Se il progetto deve supportare ambienti molto datati, è possibile valutare entrambe le forme, ma normalmente non è necessario.
Gestire il colore con currentColor
Nei tracciati è stato utilizzato stroke="currentColor". Questa parola chiave eredita il valore CSS della proprietà color dell’elemento SVG o del suo contenitore. Di conseguenza, la stessa icona può assumere colori diversi senza modificare il simbolo originale.
<span style="color: darkgreen;">
<svg width="24" height="24" viewBox="0 0 24 24" aria-hidden="true">
<use href="#icon-check"></use>
</svg>
</span>
In un progetto reale è preferibile gestire il colore con classi CSS invece di usare direttamente l’attributo style. Il vantaggio principale è che la libreria di icone resta indipendente dalla grafica del singolo componente.
Accessibilità delle istanze
Un’icona puramente decorativa deve essere ignorata dai lettori di schermo. Per questo si usano aria-hidden="true" e focusable="false". Il testo visibile del pulsante o del collegamento fornisce già l’informazione necessaria.
Quando l’icona comunica un’informazione importante, invece, deve avere un nome accessibile. Nell’esempio l’icona di conferma utilizza role="img", un elemento <title> e l’attributo aria-labelledby.
È buona pratica non affidarsi soltanto all’icona per descrivere un’azione. Un pulsante con una lente, per esempio, dovrebbe contenere anche la parola “Cerca” oppure un’etichetta accessibile esplicita.
Best practice
- Usa ID descrittivi: nomi come
icon-searchoicon-chevron-rightsono più comprensibili di identificatori generici comeshape-1. - Mantieni un sistema di coordinate uniforme: usare un viewBox comune semplifica l’allineamento e il dimensionamento delle icone.
- Preferisci
currentColor: permette di ereditare il colore dal contesto e riduce la duplicazione del codice. - Nascondi lo sprite: il contenitore delle definizioni non deve occupare spazio visivo. Puoi usare dimensioni nulle e posizionamento assoluto.
- Non inserire titoli duplicati: se il testo del pulsante descrive già l’azione, l’icona deve essere decorativa.
- Controlla il contrasto: il colore dell’icona deve essere sufficientemente distinguibile dallo sfondo, soprattutto quando trasmette informazioni.
- Usa tracciati semplici: per le icone di interfaccia è preferibile mantenere il markup leggero, evitando dati inutili esportati dai programmi di grafica.
- Centralizza le modifiche: modificando il simbolo nello sprite, tutte le istanze vengono aggiornate automaticamente.
Per progetti molto grandi, lo sprite può anche essere generato automaticamente durante la fase di build partendo da file SVG separati. Tuttavia, il principio resta identico: ogni elemento possiede un identificatore stabile e viene inserito nella pagina tramite <use>.
Riepilogo
Uno sprite SVG inline basato su <symbol> e <use> consente di creare una libreria di icone efficiente e facilmente manutenibile. Le definizioni vengono scritte una sola volta, mentre ogni istanza può avere dimensioni e contesto differenti.
La combinazione tra viewBox, currentColor e attributi ARIA permette di ottenere icone coerenti, personalizzabili e accessibili. Ricorda di distinguere sempre tra icone decorative e icone informative: nel primo caso usa aria-hidden="true", nel secondo fornisci un nome accessibile significativo.
