Per rimuovere lo spazio imprevisto attorno a un’istanza SVG use, individua se dipende dal viewBox sorgente, dall’adattamento delle proporzioni o dalla line box CSS circostante. Questa guida mostra come diagnosticare e correggere ciascuna causa mantenendo prevedibili le coordinate di posizionamento.

Il compito consiste in una piccola modifica a una pagina web desktop: posizionare con precisione una forma riutilizzabile all’interno di un SVG, quindi adattare il layout HTML circostante come desiderato. Puoi seguire gli esempi in un editor di testo semplice sul tuo Mac e aprire il file HTML salvato in un browser desktop aggiornato.

Quale sistema di coordinate controlla lo spazio?

Ci sono tre limiti da esaminare: il riquadro CSS dell’elemento SVG esterno, il viewport usato per un simbolo referenziato e la forma effettiva all’interno del simbolo. Il W3C distingue esplicitamente un viewport SVG dal viewport CSS del browser. Un viewBox mappa le coordinate utente SVG in un viewport SVG; non descrive la finestra del browser. Sistemi di coordinate, trasformazioni e unità — SVG 2

Ad esempio, x="20" su un elemento use fornisce un offset nel suo sistema di coordinate SVG. Non significa 20 pixel CSS dal bordo sinistro della finestra del browser. Le trasformazioni di scala e quelle degli elementi antenati possono cambiare la posizione di tale offset nella pagina. La specifica SVG descrive il posizionamento use come una traslazione aggiuntiva, con un comportamento distinto dal layout dei riquadri CSS. Struttura del documento — SVG 2

Inizia con questa tabella decisionale. È una sequenza diagnostica derivata dai meccanismi di layout documentati, non un elenco di soluzioni intercambiabili.

Cosa osservi Cosa controllare per prima cosa Correzione probabile
Una sottile striscia sotto l’intero SVG Formattazione in linea e interlinea dell’elemento genitore Imposta l’SVG autonomo come elemento a blocco oppure regola il suo allineamento in linea
Spazio vuoto all’interno di ogni grafica ripetuta Coordinate della forma rispetto al viewBox del simbolo Restringi i limiti sorgente se l’inserto non è intenzionale
Spazio aggiuntivo su due lati di un’istanza del simbolo Dimensioni dell’istanza rispetto al rapporto viewBox Fai corrispondere i rapporti o scegli una modalità di adattamento intenzionale
Posizionamento locale corretto ma posizione errata nella pagina Unità utente SVG rispetto alle coordinate del viewport del browser Converti le coordinate prima di assegnare x e y
Modificare le dimensioni dell’istanza non produce effetti L’elemento a cui si applica href Per l’adattamento usa un simbolo che definisca un viewport, oppure trasforma la geometria

Riproduci lo spazio con un esempio locale completo

Salva il seguente documento completo come svg-spacing.html in un editor di testo semplice, quindi aprilo nel browser. Usa solo etichette e rettangoli di esempio, senza librerie o file esterni. I rettangoli chiari indicano i viewport previsti per le istanze; quelli più scuri rappresentano la grafica riutilizzata.

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>SVG spacing example</title>
  <style>
    body {
      margin: 24px;
      font: 16px system-ui, sans-serif;
    }
    #canvas {
      display: block;
      width: 320px;
      height: 200px;
      outline: 1px solid #687580;
      background: #fff;
    }
    .viewport-guide { fill: #e4edf2; }
    .artwork { fill: #356b8c; }
    text { fill: #253744; font-size: 14px; }
  </style>
</head>
<body>
  <p>Two instances with different source bounds and fitting dimensions.</p>
  <svg id="canvas" xmlns="http://www.w3.org/2000/svg"
       width="320" height="200" viewBox="0 0 320 200"
       role="img" aria-labelledby="drawing-title">
    <title id="drawing-title">Padded and tightly fitted rectangles</title>
    <defs>
      <symbol id="padded" viewBox="0 0 100 100">
        <rect id="source-shape" class="artwork"
              x="20" y="20" width="60" height="60" />
      </symbol>
      <symbol id="tight" viewBox="20 20 60 60">
        <rect class="artwork"
              x="20" y="20" width="60" height="60" />
      </symbol>
    </defs>

    <rect class="viewport-guide"
          x="20" y="20" width="120" height="60" />
    <use href="#padded" x="20" y="20" width="120" height="60" />
    <text x="160" y="55">Padded source</text>

    <rect class="viewport-guide"
          x="20" y="110" width="60" height="60" />
    <use id="tight-instance" href="#tight"
         x="20" y="110" width="60" height="60" />
    <text x="110" y="145">Tight source</text>
  </svg>
</body>
</html>

Entrambe le istanze impostano esplicitamente le proprie dimensioni. In questo modo, durante l’analisi dello spazio, non ci si affida a dimensioni implicite. MDN documenta che use riutilizza il contenuto SVG referenziato e specifica che width e height influiscono sull’adattamento quando l’elemento di destinazione è un SVG o un simbolo con un viewBox. L’esempio usa l’attributo attuale href. MDN: use

Calcola dove inizia davvero il primo rettangolo

Il primo sorgente ha un viewBox di 100 per 100, ma il suo rettangolo occupa solo le coordinate da 20 a 80 in entrambe le direzioni. Il viewport richiesto per l’istanza misura 120 per 60. Con l’adattamento predefinito xMidYMid meet, la scala è il valore più piccolo tra 120 / 100 e 60 / 100: 0.6. Il viewBox scalato occupa 60 per 60, lasciando 30 unità su ciascun lato orizzontale. Questo corrisponde all’algoritmo di trasformazione del viewport del W3C. SVG 2: calcolo della trasformazione equivalente di un viewport SVG

Con questi valori d’esempio, il rettangolo disegnato inizia orizzontalmente a 20 + 30 + 20 × 0.6 = 62 e verticalmente a 20 + 20 × 0.6 = 32. Le sue dimensioni sono 60 × 0.6 = 36 in entrambe le direzioni. Il calcolo è stato verificato con una piccola elaborazione deterministica; si tratta di valori calcolati, non di misurazioni ottenute con un test del browser.

La seconda istanza modifica due valori indipendenti: i suoi limiti sorgente diventano 20 20 60 60 e il viewport dell’istanza diventa 60 per 60. Il rettangolo riempie quindi quel viewport e inizia alla coordinata SVG (20, 110). Per isolare le cause, modifica un solo valore alla volta.

Come si elimina lo spazio all’interno dell’istanza?

Correggi lo spazio indesiderato nei limiti sorgente

Un viewBox contiene quattro numeri: x minimo, y minimo, larghezza e altezza. La sua origine non deve necessariamente essere zero. Nell’esempio, viewBox="20 20 60 60" descrive i limiti esistenti del rettangolo senza riscriverne la geometria. MDN: viewBox

Prima di restringere i limiti di una grafica reale, stabilisci se il suo inserto è intenzionale. Un insieme di forme riutilizzabili può condividere un sistema di coordinate comune per mantenere coerenti dimensioni e posizioni visive. Restringere separatamente ogni simbolo può modificare tali relazioni. Mantieni limiti condivisi quando questa coerenza fa parte del progetto.

Per esaminare la geometria, getBBox() restituisce i limiti nelle coordinate utente SVG. Per impostazione predefinita, esclude tratti e marcatori e non tiene conto delle trasformazioni applicate all’elemento di destinazione o ai suoi genitori. Di conseguenza, un riquadro di delimitazione basato solo sul riempimento non basta per valutare il ritaglio di una grafica con tratti o trasformata. MDN: getBBox() di SVGGraphicsElement

Scegli come adattare rapporti d’aspetto diversi

Anche una grafica con limiti ben definiti può lasciare spazio circostante quando una sorgente quadrata viene adattata a un viewport largo. Scegli la modalità in base al risultato desiderato. Applica preserveAspectRatio al simbolo referenziato per il suo adattamento interno oppure all’SVG esterno quando analizzi la mappatura delle coordinate esterne. MDN: preserveAspectRatio

Scelta Risultato e condizione
Rapporti della sorgente e del viewport uguali Evita lo spazio dovuto all’adattamento delle proporzioni mantenendo le proporzioni della grafica
xMidYMid meet Mostra l’intero viewBox, centrato; rapporti diversi lasciano spazio
xMinYMin meet Sposta il viewBox adattato verso l’angolo in alto a sinistra; resta comunque dello spazio
none Consente una scalatura non uniforme; un quadrato può diventare un rettangolo
xMidYMid slice Copre il viewport, ma parte del contenuto sorgente si estende oltre i suoi limiti; la visibilità dipende dal ritaglio

Modificare l’allineamento sposta lo spazio dovuto all’adattamento; non rimuove un inserto già presente nella geometria sorgente. Allo stesso modo, slice non è adatto quando tutto il contenuto sorgente deve rimanere nel viewport. Queste distinzioni seguono le definizioni MDN di allineamento, meet, slice e adattamento non uniforme. MDN: preserveAspectRatio

Controlla l’elemento referenziato se le dimensioni sembrano inefficaci

Un semplice gruppo o tracciato non acquisisce un viewport di adattamento solo perché un elemento use lo referenzia. Il W3C specifica che width e height dell’istanza non hanno effetto se l’elemento referenziato non definisce un nuovo viewport. Per un adattamento prevedibile di ogni istanza, inserisci la geometria riutilizzabile in un simbolo con limiti espliciti, come sopra. Per scalare direttamente la geometria, usa una trasformazione e tieni conto del suo effetto sul posizionamento. SVG 2: layout della grafica riutilizzata

Come si elimina la striscia sotto l’SVG esterno?

Uno spazio esterno all’SVG può dipendere dalla formattazione in linea dell’HTML. WHATWG consente SVG nei contenuti di frase; la pagina circostante può quindi posizionarlo accanto al testo. Le line box CSS includono metriche del font sopra e sotto la linea di base, quindi una grafica in linea può lasciare spazio visibile sotto il proprio riquadro. Standard HTML: SVG, CSS 2: calcolo dell’interlinea

L’esempio completo imposta già display: block su #canvas, escludendo così l’SVG dalla line box in linea. Mantieni questa regola per un disegno autonomo. Per esaminare il meccanismo, modificala temporaneamente in display: inline e controlla la linea circostante.

Se l’SVG deve restare accanto al testo, prova vertical-align: bottom sull’SVG esterno e controlla l’allineamento risultante del testo. Questa proprietà allinea un riquadro di livello in linea all’interno della sua linea; non modifica i limiti del simbolo né l’adattamento interno. Altri contenuti e l’interlinea dell’elemento genitore possono comunque determinare l’altezza totale della linea. MDN: vertical-align

Considera queste dichiarazioni CSS come alternative per l’SVG esterno, non come correzioni cumulative da applicare a ogni istanza:

/* Standalone drawing */
#canvas {
  display: block;
}

/* Alternative when the drawing must stay inline */
/*
#canvas {
  display: inline;
  vertical-align: bottom;
}
*/

E se le coordinate provengono dal viewport del browser?

getBoundingClientRect() restituisce la posizione di un elemento rispetto al viewport del browser, in pixel CSS. La posizione cambia quando scorri la pagina. Questi valori appartengono a uno spazio diverso dalle coordinate utente SVG, quindi in genere è errato copiare direttamente left e top nelle proprietà x e y di un’istanza. MDN: elemento getBoundingClientRect()

Quando il dato di partenza è un punto del viewport del browser, usa una trasformazione di coordinate. getScreenCTM() fornisce la matrice di trasformazione SVG e applicarne l’inversa riconverte il punto nelle coordinate locali dell’elemento scelto. Il metodo matrixTransform() di un punto esegue la conversione. MDN: getScreenCTM(), MDN: matrixTransform()

Il seguente frammento per la console è un’estensione facoltativa del documento completo qui sopra. Converte il punto del viewport del browser (100, 150) nelle coordinate utente dell’SVG esterno e vi sposta l’istanza con limiti ben definiti. Presuppone che l’istanza dell’esempio, non trasformata, sia ancora figlia diretta di quell’SVG.

(() => {
  const canvas = document.getElementById("canvas");
  const instance = document.getElementById("tight-instance");
  if (!canvas || !instance) {
    throw new Error("Open the complete SVG spacing example first.");
  }

  const matrix = canvas.getScreenCTM();
  if (!matrix) {
    throw new Error("The SVG coordinate matrix is unavailable.");
  }

  const viewportPoint = new DOMPoint(100, 150);
  const localPoint = viewportPoint.matrixTransform(matrix.inverse());
  if (!Number.isFinite(localPoint.x) || !Number.isFinite(localPoint.y)) {
    throw new Error("The SVG coordinate matrix cannot be inverted.");
  }

  instance.setAttribute("x", String(localPoint.x));
  instance.setAttribute("y", String(localPoint.y));
})();

Il controllo dei numeri finiti è importante perché una matrice non invertibile produce componenti NaN. Ricalcola la matrice quando converti un nuovo punto dopo una variazione del layout o dello scorrimento. Se l’istanza si trova all’interno di un gruppo trasformato, converti le coordinate nel sistema di coordinate locale di quel gruppo genitore. Questo frammento è stato controllato rispetto alla documentazione dell’API; durante la ricerca non è stato eseguito in un browser. MDN: inverse() di DOMMatrixReadOnly

Per concludere, controlla separatamente i tre limiti: il riquadro SVG esterno, il viewport di adattamento del simbolo e i limiti della grafica stessa. Correggi il limite che introduce lo spazio indesiderato, quindi verifica il risultato alle dimensioni di pagina previste. In questo modo il posizionamento sarà prevedibile, senza compensare uno spazio inspiegabile con offset arbitrari.

Fonti