Definisci la grafica una sola volta in un elemento SVG <symbol>, quindi fai riferimento al suo ID con <use> all’interno di ogni SVG visibile. Assegna a ogni istanza una dimensione propria e lascia che sia il CSS a disporre il resto della pagina. Struttura del documento SVG.
Questo tutorial è rivolto a chi modifica una pagina HTML su un Mac e vuole mostrare la stessa piccola grafica accanto a diverse etichette testuali. L’esempio completo usa tessere sintetiche, HTML standard e CSS. Non richiede framework, JavaScript, immagini scaricate né una fase di compilazione.
Come può un solo simbolo generare più grafiche visibili?
Un <symbol> è un modello grafico. Non viene visualizzato da solo; un riferimento <use> crea un’istanza visibile. Inserisci la definizione una volta nel documento, poi aggiungi un piccolo contenitore SVG dove vuoi mostrare la grafica. MDN documenta entrambi gli elementi come ampiamente supportati. MDN: symbol.
È importante distinguere tra evitare di ripetere i tracciati nel codice sorgente ed evitare il lavoro di rendering del browser. Il tuo HTML contiene una sola definizione del tracciato, ma il browser crea comunque un’istanza renderizzata per ogni <use>. MDN descrive questo processo come una clonazione in un DOM non esposto. Il riutilizzo rende il codice sorgente più facile da mantenere; non significa che più grafiche visibili diventino un unico oggetto renderizzato. MDN: use.
Per una pagina con etichette e icone, mantieni le etichette in HTML e assegna a ogni icona il proprio contenitore SVG. WHATWG riconosce SVG come contenuto incorporato, di frase e di flusso in HTML, consentendo di inserire questi contenitori tra i normali contenuti della pagina. Standard HTML: SVG.
Crea una pagina completa con una definizione e tre istanze
In un editor di testo semplice sul tuo Mac, crea un file chiamato svg-reuse.html. Incolla il documento completo qui sotto, salvalo e aprilo nel browser desktop. Mantieni l’estensione .html e salva il file come testo semplice, non come documento di testo formattato.
L’esempio definisce due tessere diagonali con un solo <path>. Tre riferimenti mostrano la stessa geometria con dimensioni e colori diversi. Ogni riferimento usa href="#demo-tiles"; href senza prefisso è la forma corrente, mentre xlink:href è deprecato. MDN: attributi di use.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Reusable tile symbol</title>
<style>
body {
margin: 2rem;
font-family: system-ui, sans-serif;
color: #263445;
}
.symbol-bank {
position: absolute;
width: 0;
height: 0;
overflow: hidden;
}
.samples {
display: flex;
flex-wrap: wrap;
gap: 1.5rem;
}
.sample {
display: flex;
align-items: center;
gap: 0.75rem;
padding: 1rem;
border: 1px solid #cbd5df;
}
.icon {
display: block;
width: 24px;
height: 24px;
flex: none;
}
.icon-large { width: 48px; height: 48px; }
.icon-medium { width: 32px; height: 32px; }
.blue { color: #2457a7; }
.purple { color: #7140a0; }
</style>
</head>
<body>
<svg class="symbol-bank" width="0" height="0" aria-hidden="true">
<symbol id="demo-tiles" viewBox="0 0 24 24"
preserveAspectRatio="xMidYMid meet">
<path fill="currentColor"
d="M4 4H10V10H4Z M14 14H20V20H14Z"></path>
</symbol>
</svg>
<main>
<h1>Tile samples</h1>
<div class="samples">
<div class="sample">
<svg class="icon" width="24" height="24"
viewBox="0 0 24 24" aria-hidden="true">
<use href="#demo-tiles" width="24" height="24"></use>
</svg>
<span>Small tiles</span>
</div>
<div class="sample blue">
<svg class="icon icon-large" width="48" height="48"
viewBox="0 0 24 24" aria-hidden="true">
<use href="#demo-tiles" width="24" height="24"></use>
</svg>
<span>Large tiles</span>
</div>
<div class="sample purple">
<svg class="icon icon-medium" width="32" height="32"
viewBox="0 0 24 24" aria-hidden="true">
<use href="#demo-tiles" width="24" height="24"></use>
</svg>
<span>Medium tiles</span>
</div>
</div>
</main>
</body>
</html>
Il risultato atteso è composto da tre campioni bordati che contengono le stesse tessere diagonali. Il primo usa il colore del testo del corpo, il secondo il blu e il terzo il viola. I rispettivi riquadri SVG misurano 24, 48 e 32 pixel CSS per lato. Restringi la finestra del browser per controllare come vanno a capo i campioni.
In questo caso le forme visibili sono decorative, perché le etichette adiacenti forniscono il contenuto. Per questo i contenitori SVG usano aria-hidden="true". In questo modo vengono esclusi dall’albero di accessibilità senza essere nascosti visivamente. Riserva questo trattamento alle grafiche decorative; non applicarlo a un’immagine che trasmette informazioni non presenti nel testo. MDN: aria-hidden.
Quali impostazioni controllano il layout della pagina e quello SVG?
Ci sono tre compiti distinti: disporre i componenti HTML, dimensionare ogni riquadro SVG e adattare il disegno al riquadro. Modificare l’impostazione di un compito può lasciare invariati gli altri due.
| Compito | Impostazione nell’esempio | Cosa modificare |
|---|---|---|
| Disporre i campioni nella pagina | .samples usa flexbox e l’andata a capo |
Modifica qui la spaziatura o l’andata a capo |
| Allineare ogni grafica alla sua etichetta | .sample usa flexbox e align-items: center |
Modifica qui l’allineamento del componente |
| Impostare il riquadro SVG visualizzato | .icon e le sue classi di dimensionamento |
Modifica qui la larghezza e l’altezza CSS |
| Definire le coordinate del disegno | viewBox="0 0 24 24" |
Modificalo quando cambiano i limiti delle coordinate dell’immagine |
| Dimensionare internamente il simbolo referenziato | <use> ha larghezza e altezza pari a 24 |
Mantienile allineate all’area di coordinate interna di questo esempio |
| Adattare il disegno mantenendone le proporzioni | preserveAspectRatio="xMidYMid meet" |
Modificalo solo se vuoi un comportamento di adattamento diverso |
Flexbox dispone i figli diretti di un contenitore flessibile. Il contenitore esterno dispone quindi i campioni, mentre ogni contenitore interno dispone un SVG accanto a un’etichetta. Flexbox opera su una dimensione alla volta; le righe mandate a capo distribuiscono lo spazio in modo indipendente. Se il design richiede righe e colonne coordinate, CSS Grid è l’alternativa pertinente per il layout della pagina. MDN: concetti di base di flexbox.
All’interno di SVG, <use> segue un modello di layout diverso. I valori x e y spostano le grafiche nel sistema di coordinate SVG. Non impostano la spaziatura tra i componenti HTML. Larghezza e altezza possono dimensionare la viewport di un simbolo referenziato; non offrono un controllo di scala generale per un tracciato o un gruppo referenziato direttamente. W3C: layout delle grafiche riutilizzate.
Perché l’istanza grande mantiene dimensioni interne pari a 24?
L’viewBox dell’SVG esterno descrive un’area di coordinate di 24 per 24. Il suo riquadro CSS può misurare 48 per 48 pixel, mentre le coordinate interne restano invariate. <use> riempie quell’area interna di 24 per 24 e l’SVG esterno la adatta al riquadro visualizzato più grande. MDN definisce viewBox come quattro numeri: x minima, y minima, larghezza e altezza. MDN: viewBox.
Come calcolo illustrativo basato su questa grafica esatta, un riquadro di 48 pixel mappa 24 unità di coordinate con una scala di 48 / 24 = 2. La geometria delle tessere va dalle coordinate 4 a 20, quindi la sua estensione complessiva dipinta diventa di (20 - 4) × 2 = 32 pixel. Lo spazio restante deriva dai margini intenzionali all’interno del disegno.
Questo spiega perché aumentare la larghezza CSS di un’icona non rende necessariamente la sua forma dipinta larga quanto l’intero riquadro. Prima di modificare i margini della pagina per compensare, controlla i limiti della geometria all’interno del viewBox.
Cosa succede in un riquadro SVG rettangolare?
Con xMidYMid meet, il disegno viene ridimensionato in modo uniforme, resta centrato e si adatta all’intera viewBox all’interno della viewport disponibile. Un disegno quadrato in un rettangolo largo lascia quindi spazio ai lati. none consente la distorsione; slice mantiene le proporzioni ma permette a una parte della viewBox di estendersi oltre la viewport. Usa meet quando vuoi mantenere visibile l’intera grafica. MDN: preserveAspectRatio.
Come può ogni istanza avere un colore proprio?
Il tracciato usa fill="currentColor". Questa parola chiave assume il valore color dell’elemento, consentendo allo stesso disegno di seguire il colore del testo circostante. Nell’esempio, modificando la regola .blue o .purple cambiano sia l’etichetta sia le tessere. MDN: parola chiave currentColor.
Il risultato è possibile grazie all’ereditarietà applicata a ogni istanza. Il modello di riutilizzo SVG assegna al contenuto generato stili ereditati dall’elemento <use> ospitante. Un colore fisso dichiarato direttamente sul tracciato sorgente prevale su un riempimento ereditato fornito da un elemento genitore. Se vuoi applicare colori diversi a ciascuna istanza, lascia la geometria condivisa senza colori fissi. W3C: ambito degli stili ed ereditarietà.
Evita di affidarti a un selettore come .blue path per raggiungere un tracciato generato attraverso il contenitore visibile. Il contenuto generato appartiene all’albero shadow di riutilizzo, quindi le relazioni con gli antenati sono diverse da quelle del normale HTML annidato. Imposta color sul contenitore o sul suo elemento genitore e mantieni currentColor nella geometria sorgente. W3C: ambito degli stili ed ereditarietà.
Cosa controllare se un simbolo riutilizzato non appare correttamente?
Parti dal riferimento e procedi verso l’esterno. Questa sequenza permette di distinguere una grafica mancante da una dimensionata o posizionata in modo errato, così ogni modifica interviene su un meccanismo specifico.
- Controlla il riferimento. Verifica che
href="#demo-tiles"corrisponda aid="demo-tiles"della definizione. Mantieni quell’ID univoco nell’albero del documento. W3C: attributo id. - Controlla le dimensioni del contenitore visibile. Mantieni la classe
.symbol-banka dimensione zero solo sul contenitore delle definizioni. Ogni istanza visibile ha bisogno di un riquadro non nullo, come mostra.icon. - Controlla i limiti delle coordinate. Verifica che la grafica rientri nel
viewBoxdichiarato. Uno spazio vuoto imprevisto può derivare da coordinate di disegno inutilizzate. MDN: viewBox. - Controlla il tipo di elemento referenziato. Se hai sostituito il simbolo con un riferimento diretto a un tracciato, modificare larghezza e altezza di
<use>non lo ridimensionerà allo stesso modo. Per questo schema, ripristina il simbolo e il suoviewBox. MDN: use. - Controlla le dichiarazioni dei colori. Cerca colori fissi nella sorgente prima di aggiungere altri selettori per le istanze.
- Controlla il contenitore della pagina. Se la grafica viene visualizzata correttamente ma è troppo distante dall’etichetta, modifica lo spazio o l’allineamento CSS del componente. MDN: concetti di base di flexbox.
Quando integri l’esempio in una pagina esistente, inserisci una volta il banco dei simboli, unisci il CSS e copia solo il contenitore SVG visibile negli altri componenti. Il piccolo documento è stato sottoposto a controlli strutturali per verificare elementi bilanciati, ID univoci e tre riferimenti risolti in un’unica definizione del tracciato; questi controlli non confermano il rendering nel browser. Apri la pagina nei browser per Mac che vuoi supportare e controlla dimensioni, spaziatura e colori risultanti.
Per modificare il disegno condiviso, intervieni sulla sua unica definizione del tracciato. Per modificare una singola istanza, cambia le dimensioni del suo contenitore o il colore ereditato. Mantenere separate queste responsabilità consente di riutilizzare la grafica e di controllare con precisione dove appare ogni istanza.
Fonti
- Struttura del documento — SVG 2 — W3C.
- Standard HTML, edizione per gli sviluppatori Web: SVG — WHATWG.
<symbol>— MDN Web Docs.<use>— MDN Web Docs.- Concetti di base di flexbox — MDN Web Docs.
- viewBox — MDN Web Docs.
- preserveAspectRatio — MDN Web Docs.
- Tipo CSS
<color>— MDN Web Docs. - ARIA: attributo aria-hidden — MDN Web Docs.