Riquadri SVG: misurare le coordinate giuste
Confronta getBBox e getBoundingClientRect su grafica SVG trasformata. Posiziona le sovrapposizioni, verifica i limiti dei contorni e adatta un viewBox con un margine esplicito.
In questa pagina
Usa getBBox() quando ti servono i limiti di un elemento SVG nelle sue coordinate utente. Usa getBoundingClientRect() quando ti serve un rettangolo in pixel CSS relativo al viewport del browser. Prima di copiare uno dei risultati in una sovrapposizione o in un viewBox, controlla quale sistema di coordinate usa la destinazione.
Un emblema ruotato può avere un piccolo riquadro locale e un riquadro allineato allo schermo molto più grande. Entrambe le misure possono essere valide. Nessuna va considerata un rettangolo universale intorno a ogni pixel disegnato, soprattutto quando sono coinvolti contorni, marcatori, ritagli o filtri.
Scegli la misura per la destinazione
| Destinazione | Misura iniziale | Attenzione necessaria |
|---|---|---|
| Rettangolo nello stesso sistema di coordinate SVG | getBBox() | Assegna al rettangolo il contesto di trasformazione corrispondente |
| Bordo di selezione HTML fisso | getBoundingClientRect() | Mantienilo nelle coordinate del viewport e aggiornalo quando cambia il layout |
| ViewBox SVG radice intorno a un gruppo trasformato | Riquadro locale più una trasformazione delle coordinate | Converti in unità utente della radice prima dell'adattamento |
| Ritaglio che include contorni ed effetti | Un procedimento di misurazione dei limiti verificato separatamente | Non presumere che un riquadro geometrico di base includa tutto il disegno |
La documentazione MDN di getBBox() descrive i limiti geometrici locali e i controlli facoltativi per contorni, marcatori e ritagli. La trasformazione dell'elemento misurato e quelle degli antenati non sono incluse in quel risultato locale. I discendenti di un gruppo contribuiscono comunque alla geometria del gruppo, incluso il loro posizionamento al suo interno.
La documentazione MDN di getBoundingClientRect() descrive coordinate relative al viewport. Lo scorrimento cambia quella relazione tra coordinate. Questi valori in pixel CSS non sono automaticamente unità utente SVG o dimensioni fisiche di stampa.

Misura un emblema originale trasformato
Questo campione contiene un anello verde petrolio con un'apertura rettangolare e un triangolo dorato separato. Entrambi hanno un contorno spesso con giunzioni tonde. Il gruppo è traslato, ruotato e scalato.
<svg id="scene" width="600" height="300" viewBox="0 0 300 150"
xmlns="http://www.w3.org/2000/svg" style="overflow:visible">
<g id="art" transform="translate(100 35) rotate(25) scale(1.2)"
stroke="#17364c" stroke-width="10" stroke-linejoin="round">
<path fill="#147d78" fill-rule="evenodd"
d="M0 0H80V60H0Z M20 20H60V40H20Z" />
<path fill="#e5a340" d="M100 50L120 10L140 50Z" />
</g>
</svg>
<script>
const art = document.querySelector("#art");
const local = art.getBBox();
const screen = art.getBoundingClientRect();
</script>Le coordinate locali vanno da 0 a 140 in orizzontale e da 0 a 60 in verticale. Il foro influisce sull'interno della forma, ma non riduce quelle estensioni esterne.
Abbiamo aperto questa geometria in Chrome e l'abbiamo misurata con un piccolo strumento di test. A dimensioni di visualizzazione di 600 × 300 pixel CSS, getBBox() ha restituito x=0, y=0, width=140, height=60. Il rettangolo client misurava circa 365.376 × 272.508 pixel CSS. La sua posizione sullo schermo dipendeva da dove si trovava l'SVG nella pagina.
Dopo aver cambiato le dimensioni di visualizzazione in 300 × 150, il riquadro locale è rimasto 140 × 60. Il rettangolo client è diventato circa 182.688 × 136.254, metà delle dimensioni precedenti. La geometria sorgente non era cambiata; era cambiata la sua mappatura sulla pagina.
Questi numeri descrivono questo campione nel browser testato. Non sono un confronto tra motori di browser o una specifica per il riquadro di selezione di ogni editor.
Disegna ogni bordo nel proprio sistema di coordinate
Per un bordo locale, usa le coordinate restituite e la stessa trasformazione del gruppo misurato. Inseriscilo come elemento fratello così non entra a far parte della misura successiva:
const scene = document.querySelector("#scene");
const box = art.getBBox();
const outline = document.createElementNS("http://www.w3.org/2000/svg", "rect");
for (const key of ["x", "y", "width", "height"]) {
outline.setAttribute(key, box[key]);
}
outline.setAttribute("transform", art.getAttribute("transform"));
outline.setAttribute("fill", "none");
outline.setAttribute("stroke", "olive");
scene.append(outline);Questa copia diretta della trasformazione è appropriata per questo campione perché grafica e bordo condividono lo stesso padre. Un rettangolo inserito altrove richiede una mappatura tramite matrice tra i due sistemi di coordinate.
Per un bordo HTML, inserisci un div direttamente sotto body con posizionamento fisso e nessun antenato contenitore trasformato:
const box = art.getBoundingClientRect();
Object.assign(overlay.style, {
position: "fixed",
boxSizing: "border-box",
pointerEvents: "none",
border: "2px dashed coral",
left: `${box.x}px`,
top: `${box.y}px`,
width: `${box.width}px`,
height: `${box.height}px`,
});Qui overlay è il tuo elemento bordo esistente. Ripeti la misura quando scorri, ridimensioni o cambi layout o trasformazione della grafica. Se usi invece un posizionamento relativo al documento, considera gli offset di scorrimento; se usi un contenitore posizionato, considera il sistema di coordinate di quel contenitore. Mescolare queste regole di posizionamento è una causa comune dello spostamento di un rettangolo altrimenti corretto.
Il nostro strumento di test mostrava entrambi i bordi. Il rettangolo locale si inclinava con anello e triangolo, mentre quello HTML tratteggiato restava orizzontale e verticale. Il contorno spesso si estendeva oltre alcune parti dei bordi geometrici.
Testa le opzioni dei contorni anziché presumere il supporto
Il riquadro locale predefinito esclude la larghezza del contorno. MDN documenta getBBox({ stroke: true }), ma il parametro delle opzioni ha considerazioni di compatibilità separate dal metodo senza argomenti disponibile da tempo.
Nel nostro campione Chrome, passare { stroke: true } ha restituito lo stesso riquadro 140 × 60 della chiamata senza argomenti. Anche rimuovere il contorno di 10 unità ha lasciato invariato il rettangolo client. Il bordo scuro visibile cambiava chiaramente, quindi nessuno dei risultati di quel test rappresentava l'intera estensione del disegno.
Una chiamata che accetta un oggetto di opzioni senza generare un errore non basta a dimostrare che abbia rispettato l'opzione. Testa una forma nota con contorno e controlla le dimensioni restituite nel browser di destinazione. Usa le definizioni dei riquadri SVG per distinguere limiti dell'oggetto, del contorno e decorati.
Non generalizzare una regola di margine pari a metà contorno a ogni forma. Giunzioni miter, marcatori, contorni che non cambiano spessore con la scala, ombre e filtri possono estendersi diversamente. Per un semplice campione con giunzioni tonde sotto il tuo controllo, un margine esplicito più l'ispezione visiva possono bastare. Per un ritagliatore automatico di esportazione, quei casi richiedono gestione deliberata.
Converti un riquadro locale prima di adattare il viewBox radice
Non incollare mai direttamente x, y, width e height del rettangolo client nel viewBox SVG. Quei valori includono il posizionamento nella pagina e usano un sistema di unità diverso.
Per il campione, mappa i quattro angoli del riquadro locale nelle coordinate utente dell'SVG radice. La documentazione MDN di getScreenCTM() descrive la matrice usata per mappare le coordinate SVG verso il viewport del documento. Combinare la matrice della grafica con l'inversa della matrice radice rimuove quella mappatura condivisa sullo schermo:
const box = art.getBBox();
const rootMatrix = scene.getScreenCTM();
const artMatrix = art.getScreenCTM();
if (!rootMatrix || !artMatrix) throw new Error("SVG is not measurable");
const toRoot = rootMatrix.inverse().multiply(artMatrix);
const corners = [
[box.x, box.y],
[box.x + box.width, box.y],
[box.x + box.width, box.y + box.height],
[box.x, box.y + box.height],
].map(([x, y]) => new DOMPoint(x, y).matrixTransform(toRoot));
const xs = corners.map(p => p.x);
const ys = corners.map(p => p.y);
const x = Math.min(...xs);
const y = Math.min(...ys);
const width = Math.max(...xs) - x;
const height = Math.max(...ys) - y;
const padding = 12; // Chosen for this simple fixture, in root user units.
scene.setAttribute("viewBox", [
x - padding, y - padding,
width + 2 * padding, height + 2 * padding,
].join(" "));Questo presuppone un SVG renderizzato con trasformazioni bidimensionali invertibili. Mappare gli angoli di un rettangolo locale fornisce un involucro conservativo allineato agli assi, non necessariamente il riquadro più stretto possibile intorno a ogni curva trasformata.
Lo strumento di test ha prodotto un viewBox di circa 57.571 23 206.688 160.254 con quel margine. Abbiamo esaminato il risultato e il contorno con giunzioni tonde del campione restava nell'area di visualizzazione. La visualizzazione larga aveva ancora spazio laterale perché il viewBox adattato aveva proporzioni diverse; adattare non significa deformare.
Se ti serve un perno anziché un ritaglio, la guida a transform-origin spiega come i riquadri di riferimento influiscono sulla rotazione. Per le dimensioni fisiche di importazione, usa il procedimento di diagnosi delle dimensioni SVG.
Misura la geometria che intendi modificare
Se la sorgente esiste soltanto come PNG o JPG e ti servono forme modificabili, PerfectVector può recuperare un SVG prima della misurazione. Esamina tracciati, aperture, contorni ed eventuali contenuti raster conservati. Un riquadro indica dove si estende la geometria; non dimostra che il ricalco sia accurato o che ogni dettaglio visibile sia modificabile.
Un SVG esistente può essere misurato direttamente. La guida alla modifica degli SVG aiuta a identificare ciò che hai realmente, mentre la panoramica sulla vettorializzazione delle immagini spiega il passaggio precedente di conversione.
Per grafica soltanto raster, prova la sorgente in PerfectVector, esamina i contorni recuperati, poi misura il gruppo che inserirai o esporterai. Mantieni un margine e controlla i bordi visibili finali prima di trattare il risultato come un ritaglio di consegna.
FAQ
Perché i due metodi restituiscono larghezze diverse? Usano sistemi di coordinate diversi. Il riquadro SVG locale descrive la geometria in unità utente, mentre il rettangolo client descrive i limiti relativi al viewport in pixel CSS dopo la mappatura sulla pagina. Scala e rotazione possono cambiare quelle dimensioni.
Un riquadro mi dice se la grafica ha un foro? No. Un rettangolo registra le estensioni esterne, non la topologia interna. Un rettangolo pieno e un anello con gli stessi bordi esterni possono avere lo stesso riquadro. Esamina tracciati e regole di riempimento per controllare le aperture.
Posso usare il rettangolo client come viewBox? Non direttamente. Converti prima la geometria interessata nelle coordinate utente dell'SVG radice. Posizione sullo schermo e dimensioni in pixel CSS non vanno copiate in un rettangolo di coordinate sorgente.
Fonti
- MDN getBBox — Definisce i limiti SVG locali e i controlli di misurazione facoltativi.
- MDN getBoundingClientRect — Spiega rettangoli relativi al viewport e scorrimento.
- Definizioni dei riquadri SVG — Distingue limiti geometrici dell'oggetto, del contorno e decorati.
- MDN getScreenCTM — Documenta la matrice usata per collegare coordinate SVG e viewport.
Altro dal blog

Ordine delle trasformazioni SVG: scala e posizione
Confronta l'ordine di translate e scale in SVG con un logo misurato. Usa gruppi annidati, segui un punto e posiziona la grafica senza cambiare i tracciati sorgente.

Immagini SVG in Graphviz: rendile portabili
Aggiungi grafica SVG a un nodo Graphviz, esamina il riferimento all'immagine e confronta un pacchetto completo, un diagramma spostato e una copia autonoma.