PerfectVector
Par Irene Kim9 min de lecture

Boîtes englobantes SVG : les bonnes coordonnées

Compare getBBox et getBoundingClientRect sur un SVG transformé. Place les superpositions, teste les limites de contour et ajuste un viewBox avec une marge explicite.

Sur cette page

Utilise getBBox() lorsque tu as besoin des limites d’un élément SVG dans ses propres coordonnées utilisateur. Utilise getBoundingClientRect() lorsque tu as besoin d’un rectangle en pixels CSS par rapport à la zone d’affichage du navigateur. Avant de copier l’un ou l’autre résultat dans une superposition ou un viewBox, vérifie le système de coordonnées utilisé par la destination.

Un emblème tourné peut avoir une petite boîte locale et une boîte alignée sur l’écran bien plus grande. Les deux mesures peuvent être valides. Aucune ne doit être considérée comme un rectangle universel autour de chaque pixel peint, particulièrement avec des contours, marqueurs, découpages ou filtres.

Choisis la mesure adaptée à la destination

DestinationMesure de départPrécaution nécessaire
Rectangle dans le même système de coordonnées SVGgetBBox()Donne au rectangle le contexte de transformation correspondant
Contour de sélection HTML fixegetBoundingClientRect()Conserve les coordonnées de zone d’affichage et actualise-les lorsque la mise en page change
viewBox SVG racine autour d’un groupe transforméBoîte locale plus transformation de coordonnéesConvertis en unités utilisateur racines avant l’ajustement
Recadrage incluant contours et effetsMéthode de limites vérifiée séparémentNe suppose pas qu’une boîte de géométrie simple inclut toute la peinture

La documentation MDN de getBBox() décrit les limites géométriques locales et les contrôles facultatifs de contour, marqueur et découpage. La transformation de l’élément mesuré et celles de ses ancêtres ne sont pas incluses dans ce résultat local. Les descendants d’un groupe contribuent toutefois à sa géométrie, y compris leur placement à l’intérieur.

La référence MDN de getBoundingClientRect() décrit des coordonnées relatives à la zone d’affichage. Le défilement change cette relation. Ces valeurs en pixels CSS ne sont pas automatiquement des unités utilisateur SVG ou des dimensions physiques d’impression.

Illustration d’un emblème incliné avec un rectangle local incliné correspondant à l’intérieur d’un rectangle d’écran horizontal
Illustration conceptuelle de deux systèmes de coordonnées. Un rectangle local suit les axes du dessin ; un rectangle de zone d’affichage reste aligné sur l’écran.

Mesure un emblème original transformé

Cet exemple contient un anneau bleu-vert avec une ouverture rectangulaire et un triangle doré distinct. Les deux ont un contour épais à raccords arrondis. Le groupe est déplacé, tourné et redimensionné.

<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>

Les coordonnées locales vont de 0 à 140 horizontalement et de 0 à 60 verticalement. Le trou affecte l’intérieur de la forme, mais ne réduit pas ces limites extérieures.

Nous avons ouvert cette géométrie dans Chrome et l’avons mesurée avec un petit dispositif de test. À une taille d’affichage de 600 × 300 pixels CSS, getBBox() a renvoyé x=0, y=0, width=140, height=60. Le rectangle client mesurait environ 365.376 × 272.508 pixels CSS. Sa position à l’écran dépendait de l’emplacement du SVG sur la page.

Après avoir changé la taille d’affichage en 300 × 150, la boîte locale est restée à 140 × 60. Le rectangle client est devenu environ 182.688 × 136.254, soit la moitié des dimensions précédentes. La géométrie source n’avait pas changé ; sa correspondance avec la page avait changé.

Ces nombres décrivent cet exemple dans le navigateur testé. Ce ne sont ni une comparaison de moteurs de navigateur ni une spécification de la boîte de sélection de tous les éditeurs.

Dessine chaque contour dans son système de coordonnées

Pour un contour local, utilise les coordonnées renvoyées et la même transformation que le groupe mesuré. Place-le comme élément frère afin qu’il ne participe pas à la mesure suivante :

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);

Cette copie directe de la transformation convient à cet exemple, car le dessin et le contour partagent le même parent. Un rectangle inséré ailleurs nécessite une correspondance matricielle entre les deux systèmes de coordonnées.

Pour un contour HTML, place un div directement sous body, avec un positionnement fixe et sans ancêtre contenant transformé :

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`,
});

Ici, overlay est ton élément de contour existant. Mesure à nouveau lors du défilement, du redimensionnement ou d’une modification de la mise en page ou de la transformation du dessin. Si tu utilises plutôt un positionnement dans le document, tiens compte des décalages de défilement ; si tu utilises un conteneur positionné, tiens compte de son système de coordonnées. Mélanger ces règles de placement explique souvent pourquoi un rectangle par ailleurs correct semble décalé.

Notre dispositif affichait les deux contours. Le rectangle local s’inclinait avec l’anneau et le triangle, tandis que le rectangle HTML en pointillés restait horizontal et vertical. Le contour épais dépassait certaines parties des contours géométriques.

Teste les options de contour au lieu de supposer leur prise en charge

La boîte locale par défaut exclut la largeur du contour. MDN documente getBBox({ stroke: true }), mais la compatibilité du paramètre d’options doit être considérée séparément de celle de la méthode sans argument, présente depuis longtemps.

Dans notre exemple Chrome, transmettre { stroke: true } a renvoyé la même boîte de 140 × 60 que l’appel sans argument. Supprimer le contour de 10 unités a aussi laissé le rectangle client inchangé. La bordure sombre visible changeait clairement : aucun des deux résultats de ce test ne représentait donc toute l’empreinte peinte.

Un appel qui accepte un objet d’options sans lever d’erreur ne suffit pas à prouver qu’il respecte l’option. Teste une forme avec contour connue et vérifie les dimensions renvoyées dans ton navigateur cible. Utilise les définitions des boîtes englobantes SVG pour distinguer les limites d’objet, de contour et de décorations.

Ne généralise pas une marge d’une demi-largeur de contour à toutes les formes. Les raccords en onglet, marqueurs, contours non redimensionnés, ombres et filtres peuvent s’étendre différemment. Pour un exemple simple à raccords arrondis que tu contrôles, une marge explicite et une inspection visuelle peuvent suffire. Pour un outil automatique de recadrage d’export, ces cas doivent être traités délibérément.

Convertis une boîte locale avant d’ajuster le viewBox racine

Ne copie jamais directement les x, y, width et height du rectangle client dans le viewBox SVG. Ces valeurs incluent le positionnement sur la page et utilisent un autre système d’unités.

Pour l’exemple, convertis les quatre coins de la boîte locale dans les coordonnées utilisateur du SVG racine. La référence MDN de getScreenCTM() décrit la matrice utilisée pour convertir les coordonnées SVG vers la zone d’affichage du document. Combiner la matrice du dessin avec la matrice racine inverse retire cette correspondance commune avec l’écran :

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(" "));

Cela suppose un SVG rendu avec des transformations bidimensionnelles inversibles. Convertir les coins d’un rectangle local donne une enveloppe englobante calculée par excès et alignée sur les axes, et pas nécessairement la boîte la plus serrée autour de chaque courbe transformée.

Le dispositif a produit un viewBox d’environ 57.571 23 206.688 160.254 avec cette marge. Nous avons inspecté le résultat et le contour arrondi de l’exemple est resté dans la zone d’affichage. L’affichage large conservait de l’espace latéral, car le viewBox ajusté avait un autre rapport de proportions ; ajuster ne signifie pas étirer.

Si tu as besoin d’un pivot plutôt que d’un recadrage, le guide transform-origin explique comment les boîtes de référence influencent la rotation. Pour les dimensions physiques d’importation, utilise la méthode de diagnostic des tailles SVG.

Mesure la géométrie que tu veux modifier

Si ta source existe seulement sous forme PNG ou JPG et que tu as besoin de formes modifiables, PerfectVector peut reconstruire un SVG avant la mesure. Inspecte ses tracés, ouvertures, contours et tout contenu matriciel conservé. Une boîte englobante indique où s’étend la géométrie ; elle ne prouve pas la précision du traçage ni que chaque détail visible soit modifiable.

Un SVG existant peut être mesuré directement. Le guide de modification SVG aide à identifier ce que tu possèdes réellement, tandis que la présentation de la vectorisation d’images explique la conversion en amont.

Pour un dessin uniquement matriciel, essaie ta source dans PerfectVector, inspecte les contours reconstruits, puis mesure le groupe à placer ou exporter. Conserve une marge et vérifie les bords finaux visibles avant de considérer le résultat comme un recadrage de livraison.

FAQ

Pourquoi les deux méthodes renvoient-elles des largeurs différentes ? Elles utilisent des systèmes de coordonnées différents. La boîte SVG locale décrit la géométrie en unités utilisateur, tandis que le rectangle client décrit ses limites relatives à la zone d’affichage en pixels CSS après la correspondance avec la page. La mise à l’échelle et la rotation peuvent modifier ces dimensions.

Une boîte englobante m’indique-t-elle si le dessin possède un trou ? Non. Un rectangle enregistre les limites extérieures, et non la topologie intérieure. Un rectangle plein et un anneau aux mêmes bords extérieurs peuvent avoir la même boîte englobante. Inspecte les tracés et les règles de remplissage pour vérifier les ouvertures.

Puis-je utiliser le rectangle client comme viewBox ? Pas directement. Convertis d’abord la géométrie concernée dans les coordonnées utilisateur du SVG racine. La position à l’écran et les dimensions en pixels CSS ne doivent pas être copiées dans un rectangle de coordonnées sources.

Sources

  1. MDN getBBox — Définit les limites SVG locales et les contrôles de mesure facultatifs.
  2. MDN getBoundingClientRect — Explique les rectangles relatifs à la zone d’affichage et le défilement.
  3. Définitions des boîtes englobantes SVG — Distingue les limites géométriques d’objet, de contour et de décorations.
  4. MDN getScreenCTM — Documente la matrice qui relie les coordonnées SVG et celles de la zone d’affichage.

Plus depuis le blog

Repartez d’un SVG plus net
et plus facile à modifier